题目示例:17个人围一桌,轮番报数,报到3的退出,知道桌上只留下1人
/*
* 约瑟夫环普通算法
* totalCount 总数
* removeIndex 到几移除
* return 最后移除者索引
*/
public static int yueSeFuHuanSimple(int totalCount, int removeIndex) {
// 构造初始数组,true代表存在,false代表移除
boolean people[] = new boolean[totalCount];
for (int i = 0; i < totalCount; i++) {
people[i] = true;
}
// removeCount:已移除数量,i:遍历索引,j:辅助判别removeIndex
int removeCount = 0;
for (int i = 0, j = 0;; i++) {
// 1.如果存在,j自增,如果j为removeIndex,当前位置元素变false,代表移除,j重置,removeCount自增
if (people[i]) {
j++;
if (j == removeIndex) {
System.out.println("移除索引:" + i);
people[i] = false;
j = 0;
removeCount++;
}
}
// 2.如果全部移除,返回当前索引,代表最后移除者
if (removeCount == totalCount) {
System.out.println("约瑟夫环结果索引:" + i);
return i + 1;
}
// 3.本次遍历所有元素后,重置i再次遍历,i重置为-1是因为有i++
if (i == totalCount - 1) {
i = -1;
}
}
}
/*
* 约瑟夫环简洁算法
* totalCount 总数
* removeIndex 到几移除
* return 最后移除者索引
*/
public static int yueSeFuHuanConsise(int totalCount, int removeIndex) {
ArrayList<String> data = new ArrayList<String>();
for (int i = 0; i <= totalCount - 1; i++) {
data.add(i + "");
}
// search:计算在当前数组(每次移除后,数组是变化的)中,被移除的索引
int search = 0;
// 共需要移除totalCount - 1个元素,每次循环代表一次移除
for (int i = 0; i < totalCount - 1; i++) {
// 间隔removeIndex-1个位置的元素
search += removeIndex - 1;
// 取模得到当前数组被移除的将是哪一个
search %= data.size();
System.out.println("移除索引:" + data.remove(search));
}
System.out.println("约瑟夫环结果索引:" + data.get(0).toString());
return Integer.parseInt(data.get(0).toString());
}