约瑟夫环,就是一群人站成一圈,每个人依次杀死身边的人,找出最后存活的那个人。
本文参考b站某up思想,用经验归纳法来找出约瑟夫环的规律。
若约瑟夫环长度(即总人数n)为2的次方,如1、2、4、8、16等,则第一个人存活。
若不是长度2的次方,则第2(n-a)+1个人存活(a为离n最近的2的次方数)。
// 判断是否是2的n次方
public static boolean isTwoMi(int x) {
if (x < 1) {
return false;
}
int m = x & (x - 1);
return m == 0;
}
// n为约瑟夫环的长度,即人数
public static int Joseph(int n) {
if (n < 1) {
return -1;
}
if (isTwoMi(n)) {
return 1;
}
int i = 0;
int sum = 1;
while (sum < n) {
sum = (int) Math.pow(2, i);
i++;
}
return 2 * (n - sum / 2) + 1;
}