面试题62:圆圈中最后剩下的数字
题目:0,1,…,n-1 这 n 个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。
思路1:环形链表
在leetcode上超时了!!
代码实现:
package Question62;
public class T01 {
public static void main(String[] args) {
System.out.println(solve(5, 3));
}
public static int solve(int n, int m) {
if(n<=0) throw new RuntimeException("n小于或等于0");
Node root = new Node(0);
Node temp = root;
for(int i = 1; i < n; i++) {
temp.next = new Node(i);
temp = temp.next;
}
temp.next = root;
for(int i = 0; i < n - 1; i++) {
int count = m;
while(--count > 0) temp = temp.next;
temp.next = temp.next.next;
}
return temp.value;
}
}
class Node {
int value;
Node next;
public Node(int value) {
this.value = value;
}
}
思路2:用arrayList同样也可以模拟出环形链表
代码实现:
package Question62;
import java.util.ArrayList;
public class T02 {
public static void main(String[] args) {
System.out.println(solve(5, 1));
}
public static int solve(int n, int m) {
if(n <= 0) throw new RuntimeException("n小于等于0");
ArrayList<Integer> list = new ArrayList<>();
for(int i = 0; i < n; i++) list.add(i);
int index = 0;
while(--n > 0) {
index = (index + m - 1) % list.size();
list.remove(index);
}
return list.get(0);
}
}
思路3:数学方法
公式是这样了,至于为什么,请查看 https://blog.csdn.net/u011500062/article/details/72855826
代码实现:
package Question62;
public class T03 {
public static void main(String[] args) {
System.out.println(solve(5, 3));
}
public static int solve(int n, int m) {
if(n < 1 || m < 1) return -1;
int last = 0;
for(int i = 2; i <= n; i++) {
last = (last + m) % i;
}
return last;
}
}