#面试题62. 圆圈中最后剩下的数字
题目描述
解题思路
经典的为瑟夫环问题,出题背景还有猴子选大王。一种是用模拟环形队列来完成,一种就是数学公式递推法。前者比较直观但是在数据量大的时候要花很长时间,后者比较难懂但是效率很高。有一篇博客写的很好,搬运工系列:
约瑟夫环——公式法(递推公式)
1、递推公式法
公式:f(N,M)=(f(N−1,M)+M)%N
胜利者位置相当于是上一次胜利者往前移动m个位置
public static int lastRemaining(int n, int m) {
int win = 0; //初始值,如果n=1,那么赢的就是0号位置
for(int i = 2;i <= n;i++) {
win = (win + m)%i;
}
return win;
}
提交结果:
2、模拟队列法
注意:不能用linkedList当成环形链表,因为链表靠索引找数字需要遍历会超时,而arraylist不会
public int lastRemaining(int n, int m) {
int start = 0;
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i = 0;i < n;i++)
list.add(i);
while(n > 1) {
start = (start+m-1)%n;
list.remove(start);
n--;
}
return list.get(0);
}
提交结果:
一秒多哈哈哈哈~