题目:https://leetcode-cn.com/problems/elimination-game/
笔记 from 【宫水三叶】约瑟夫环运用题
思路一:约瑟夫环
对称性
由于从左往右
和从右往左
分别为从左端点发起,间隔删除
和从右端点发起,间隔删除
,因此整个删除过程在连续序列中[1,n]中具有对称性,两者最终剩余的编号在连续序列中也具有对称性。
公式一
f
左
(
n
)
+
f
右
(
n
)
=
n
+
1
f_左(n) + f_右(n) = n+1
f左(n)+f右(n)=n+1
- 定义
f
左
(
n
)
f_左(n)
f左(n) 为在连续序列 [1,n] 中进行
起始从左到右
的轮流换向间隔删除,最终左边剩余的编号。 - 定义
f
右
(
n
)
f_右(n)
f右(n) 为在连续序列 [1,n] 中进行
起始从右到左
的轮流换向间隔删除,最终右边剩余的编号。
【理解对称性】
比如,求1到100的和。
1和100关于50的位置对称,这样对称的一对共有50对。
每一对相加都是 1 + 100 = 101 。
和 = 101 * 50 = 5050 。
公式二
f
左
(
n
)
=
f
右
(
n
2
)
∗
2
f_左(n) = f_右(\frac{n}{2}) * 2
f左(n)=f右(2n)∗2
当我们对连续序列 [1, 2, 3, … , n] 执行了一次从左往右
的消除之后,得到的序列为 [2, 4, 6, … , i] ,新序列的长度为
n
2
\frac{n}{2}
2n,且新序列起始变为从右往左
。
最终公式
f
左
(
n
)
=
2
∗
(
n
2
+
1
−
f
(
n
2
)
)
f_左(n) = 2*( \frac{n}{2} + 1 - f(\frac{n}{2}) )
f左(n)=2∗(2n+1−f(2n))
代码
class Solution {
public int lastRemaining(int n) {
return n == 1 ? 1 : 2 * (n / 2 + 1 - lastRemaining(n / 2));
}
}