390. 消除游戏
给定一个从1 到 n 排序的整数列表。
首先,从左到右,从第一个数字开始,每隔一个数字进行删除,直到列表的末尾。
第二步,在剩下的数字中,从右到左,从倒数第一个数字开始,每隔一个数字进行删除,直到列表开头。
我们不断重复这两步,从左到右和从右到左交替进行,直到只剩下一个数字。
返回长度为 n 的列表中,最后剩下的数字。
实例:
输入:
n = 9,
21
43
65
87
9
264
8
62
6输出:
6
一、解答
思路1:
先说一个不好的实现。首先看到这个题,很容易联想到使用一个链表,然后依次删一个跳一个,正序倒序来回执行,直到长度为 1 时返回。这样确实也可以实现,但是耗时太长了,无法满足需求。
思路2:
上述思路行不通,我们只好想别的办法了。当我们仔细观察后,其实这里面隐藏着很强的规律。我们先把答案贴出来,下面再详细证明。
实现:
public int lastRemaining(int n) {
return n == 1 ? 1 : 2 * (n / 2 + 1 - lastRemaining(n / 2));
}
二、证明
假如输入为 n,我们使用 f(n)
表示 从左到右(forward) 的最终结果,使用 b(n)
表示 从右到左(backward) 的最终结果。则
规律1: 当 n = 1 时,存在 f(n) = 1, b(n) = 1
。
规律2: 对于任意 n,存在 f(n) + b(n) = n + 1
。
我们先 假设 这条规律是成立的(因为我们会在后面证明它)。我们先来看一些例子:
当 n = 1 时,由定理 1 可知:f(n) = 1, b(n) = 1,存在 f(n) + b(n) = n + 1 = 2。
当 n = 2 时,f(n) = 2, b(n) = 1,存在 f(n) + b(n) = n + 1 = 3。
当 n = 3 时,f(n) = 2, b(n) = 2,存在 f(n) + b(n) = n + 1 = 4。
当 n = 4 时,f(n) = 2, b(n) = 3,存在 f(n) + b(n) = n + 1 = 5。
…
规律3: 对于 n > 2 的情况下,f(n) = 2 * b(n / 2)
。
假如现在有一个输入为 [1,2,3,4,5,6],第一次删除后结果为 [2,4,6],可视为 2 * [1,2,3],而我们知道下一次是 “从右到左” 的,即我们可以使用 b(3) 表示 [1,2,3] “从右到左” 的执行结果,则 f(6) = 2 * b(3)
。
同样,如果输入为 [1,2,3,4,5,6,7],第一次删除后结果同上,也有 f(7) = 2 * b(3)
。
那么,对于任意数 k,我们其实都可以按照上述方式将 f(k) 表示为:f(k) = 2 * b(k / 2)
。
证明规律2正确:
我们想要证明 f(n) + b(n) = n + 1
成立,又已知 f(n) = 2 * b(n / 2)
我们可以将他们表示为:b(n) = n + 1 - f(n) = n + 1 - 2 * b(n / 2)
和 f(n) = 2 * b(n / 2) = 2 * (n / 2 + 1 - f(n / 2))
即:f(n) + b(n) = n + 1
可以表示为:2 * (n / 2 + 1 - f(n / 2)) + n + 1 - 2 * b(n / 2) = n + 1
化简可得:f(n / 2) + b(n / 2) = n / 2 + 1
所以:欲证明 f(n) + b(n) = n + 1
成立,即证明 f(n / 2) + b(n / 2) = n / 2 + 1
成立。
证明过程:
使用数学归纳法,先从前面几个例子开始,即:
当 n = 1 时,已知 f(1) = 1, b(1) = 1,f(1) + b(1) = 2 成立。
当 n = 2 时,已知 f(2) = 2, b(2) = 1,f(2) + b(2) = 3 成立。
当 n = 3 时,已知 f(3) = 2, b(3) = 2,f(3) + b(3) = 4 成立。
…
当 n = k 时,已知 f(k / 2) + b(k / 2) = k / 2 + 1 成立,所以 f(k) + b(k) = k + 1 成立。
…
最终,对于任意值 n,我们都可以说 f(n) + b(n) = n + 1。
结论:
当 n = 1 时:
f(n) = b(n) = 1。
当 n > 1 时:
f(n) = 2 * (n / 2 + 1 - f(n / 2))
b(n) = n + 1 - 2 * b(n / 2)
三、项目地址:
https://github.com/afei-cn/LeetCode/tree/master/390.%20Elimination%20Game
四、原题地址:
https://leetcode-cn.com/problems/elimination-game/description/