题目描述
0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。
样例描述
示例 1:
输入: n = 5, m = 3
输出: 3
示例 2:
输入: n = 10, m = 17
输出: 2
思路
逆推法 + 画图模拟下标映射变化
约瑟夫环问题
- 最后存活的下标一定是0,然后由此反推它在上一轮的位置,最后一直推到原始长度时,就是答案
- 最后一轮是两个人,因此从2开始递推到原始n个人
暴力做法
直接将所有位置放入链表,只要长度大于1就不断找要删除的位置,注意取模防止越界,然后用remove方法删除即可
代码
暴力做法:
class Solution {
public int lastRemaining(int n, int m) {
List<Integer> list = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
list.add(i);
}
int idx = 0;
while (n > 1) {
idx = (idx + m - 1) % n;
list.remove(idx);
n--;
}
return list.get(0);
}
}
class Solution {
public int lastRemaining(int n, int m) {
int resIdx = 0;
//反推这轮存活的下标在上一轮的下标位置,加上m表示删掉一个后重新报数
for (int i = 2; i <= n; i ++ ) {
resIdx = (resIdx + m) % i; //注意对上一轮的长度取模,环形
}
return resIdx;
}
}