public class JosephusProblem {
public static int josephus(int n, int m) {
if (n == 1) {
return 1;
} else {
// 计算上一轮问题的解(规模减1)
int prev = josephus(n - 1, m);
// 计算当前轮问题的解
return (prev + m - 1) % n + 1;
}
}
public static void main(String[] args) {
int n = 7; // 总人数
int m = 3; // 报数到m的人被杀掉
int survivor = josephus(n, m);
System.out.println("最后剩下的人的编号是: " + survivor);
}
}
问题的规模从1-n,每层递归返回上一轮最后一个编号prev,一直返回到n层就可以得到答案.
`(prev + m - 1) % n + 1` 是用来计算约瑟夫问题中的当前问题的解的一部分。让我解释一下这个表达式的含义:
- `prev`:这是递归调用 `(n - 1, m)` 后返回的结果,表示在问题规模减小一个人时的解,即上一轮的最后剩下的人的编号。
- `m`:表示每次报数要数的数字。
- `n`:表示当前问题中的总人数。
现在让我们逐步解释这个表达式:
1. `(prev + m - 1) % n`:首先,我们将上一轮的最后剩下的人的编号 `prev` 加上 `m - 1`,prev上一个淘汰的人开始数m,因为是淘汰的人不用数,所以-1。然后,我们对结果取模 `n`,这是因为人数是固定的,所以我们需要确保结果在 1 到 `n` 的范围内。
2. 最后,我们再加上1,以将结果从0到`n-1`的范围映射到1到`n`的范围内,得到的值就是当前问题中最后剩下的人的编号。
这个表达式的目的是计算当前问题的解,即在当前问题规模下最后剩下的人的编号。递归的基本情况是只剩下一个人时,此时 `prev` 为1,`m` 无关紧要,所以最后剩下的人的编号就是1。