方法1:
暴力法,使用链表存储所有数字,然后计算要删除元素的索引。
有两点需要注意:
- 链表在删除掉一个元素后,会自动将后面的元素向前补齐,因此在计算下一个被删除元素的索引时,实际增加的量应该是
m-1
; - 当索引超过链表长度时,需要从链表头开始重新计算,可以用
%
运算实现。
class Solution {
public int lastRemaining(int n, int m) {
List<Integer> list = new ArrayList<>();
for(int i=0; i<n; i++){
list.add(i);
}
int index=0;
while(n>1){
index=(index+m-1)%n;
list.remove(index);
n--;
}
return list.get(0);
}
}
方法2:
这是一个典型的 约瑟夫环 问题,可以使用反推的方法计算出最后所剩数字在一开始的下标位置。
class Solution {
public int lastRemaining(int n, int m) {
int ans = 0;
// 最后一轮剩下2个人,所以从2开始反推
for (int i = 2; i <= n; i++) {
ans = (ans + m) % i;
}
return ans;
}
}