当数字从下一轮还原映射到上一轮时,其行为有两个决定:
如何理解这一点?先以n=9为例子,从上到下分别经过了几轮筛选:
我们仿照约瑟夫环的思路,尝试还原存活节点在原数组中的编号。当只剩下一个存活节点时,其编号为1。
由现象可猜测,当存活节点从下一轮的编号还原回上一轮时,其映射关系要么为 n i + 1 = 2 n i n_{i+1}=2n_{i} ni+1=2ni,要么为 n i + 1 = 2 n i + 1 n_{i+1}=2n_i+1 ni+1=2ni+1。那么如何确定是哪一种呢?
那么如何确定当轮数组的长度是奇数还是偶数?假如n=9,首轮的轮号是0。
观察可知,第i轮数组长度是奇数或偶数,取决于其第i位上为1或者0。
综上,就可以递推出每一轮里存活节点的编号了。
class Solution:
def lastRemaining(self, n: int) -> int:
i = 32
while i >= 0 and (((1 << i) & n) == 0):
i -= 1
# 最高位为2<
d = i
alive = 1
cnt = 0
while i >= 0:
is_one = ((1 << i) & n) != 0
if is_one:
if cnt > 0:
alive *= 2
else:
if (d % 2) == (cnt % 2):
alive *= 2
else:
alive = 2 * alive - 1
cnt += 1
i -= 1
return alive
看起来讨论区用了别的做法,有用等差数列的官方题解,有用递归的【宫水三叶】约瑟夫环运用题。但本文思路是自己想的,所以就这么记着吧。