【题目描述】
AcWing 82. 圆圈中最后剩下的数字
【思路】
涉及修改和查找 使用LinkedList链表模拟环 画一个环模拟一下就能找到删除的规律了
class Solution {
public int lastRemaining(int n, int m) {
List<Integer> circle = new LinkedList<>();
for(int i = 0; i < n; i ++) circle.add(i);
int k = (m -1) % circle.size() ; //第一个要删除的位置
while( circle.size() > 1 ){
int num = circle.remove(k);
k = (k + m - 1) % circle.size();
}
return circle.get(0);
}
}
class Solution {
public int lastRemaining(int n, int m) {
List<Integer> list = new LinkedList<>();
for (int i = 0; i < n; i ++) list.add(i);
int p = 0;
while (list.size() > 1 ) {
p = (p + m - 1) % list.size(); //注意是当前的size
list.remove(p);
}
return list.get(0);
}
}
著名约瑟夫环问题:
假设n人,报k退出,幸存者下标是x;在淘汰一人后,所有人的编号相当于都变为了 (index-k)%n,幸存者也是;
那么反过来,假设已知n-1下的幸存者的下标dp[n-1],那么n人下的幸存者的下标为 (dp[n-1]+k)%n,即:
转移方程:dp[i] = (dp[i-1]+k)%i
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
int n = scan.nextInt(), k = scan.nextInt();
int idx = 0;
for(int i = 1; i <= n; i ++){
idx = (idx + k) % i;
}
System.out.println(idx + 1);
scan.close();
}
}