力扣 - 剑指 Offer 62. 圆圈中最后剩下的数字
题目
剑指 Offer 62. 圆圈中最后剩下的数字
思路1(模拟)
- 使用链表模拟删除节点
代码
class Solution {
public int lastRemaining(int n, int m) {
int index = 0;
// 初始化链表
List list = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
list.add(i);
}
// 链表首尾相接模拟删除
while (list.size() > 1) {
// 这里需要减去1,因为我们使用的是上一个删除的索引下标,但是那个元素已经删除
// 了,此时链表长度会小1,因此这里需要减去1,保证数组不会越界
index = (index + m - 1) % list.size();
list.remove(index);
}
// 返回链表的第一个元素,即最后一个元素
return list.get(0);
}
}
复杂度分析
- 时间复杂度:\(O(MN)\)
- 空间复杂度:\(O(N)\),N为链表的长度
思路2(动态规划)
- 递推
代码
class Solution {
public int lastRemaining(int n, int m) {
// 如果只有一个元素,索引下标就是0
int index = 0;
// 最后一轮淘汰剩下两个人,所以从最后一轮开始递推
for (int i = 2; i <= n; i++) {
index = (index + m) % i;
}
return index;
}
}
复杂度分析
- 时间复杂度:\(O(N)\)
- 空间复杂度:\(O(1)\)