#题目
0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。
分析
一般做法:将元素组成一个循环链表然后按要求删除第m个元素,一个一个减,一直减少到最后一个元素返回。
约瑟夫问题https://blog.csdn.net/u011500062/article/details/72855826
,详细推导请看这个博客,很详细。
约瑟夫公式:f(n,m)=(f(n-1,m)+m)%n
f(n,m)表示胜利者下标,n时圆圈里的个数,m是固定的,表示删除第m个数字。
采用递归的方式来做这道题,具体还是详细见上面博客链接里的内容,他讲的太详细了没什么扩充的。
代码
一般做法:
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 start =0;
int index =0;
while(list.size()>1){
index = (start+m-1)%list.size();
list.remove(index);
start = index;
}
return list.get(0);
}
}
递归做法:
class Solution {
//时间复杂度为O(n),空间复杂度也为O(n),递归n层
public int lastRemaining(int n, int m) {
if(n == 0) return 0;
return (lastRemaining(n-1,m)+m)%n;
}
}
class Solution {
public int lastRemaining(int n, int m) {
int res = 0;
for(int i=1;i<=n;i++){
res = (res+m)%i;
}
return res;
}
}