约瑟夫环问题描述:
已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。
有三种方法来求解这个问题:
第一种:数组。
第二种:java里的ArrayList类。
第三种:递归。
第一种数组
/**
* 数组方法求解约瑟夫环问题
* @author OnTheRoad_
*/
public class JoseCircle {
private static int[] kids;
private static int m = 10;//人数
private static int n = 3;//报数
public static void main(String[] args) {
init();
int winner = solve();
disp(winner);
}
private static void init() {
kids = new int[m];
for (int i = 0; i < kids.length; i++) {
kids[i] = i + 1;
}
}
private static int solve() {
int i = -1, count = 0, reminder = m;
while (reminder > 1) {
i = (i + 1) % m;//移到下一个
if (kids[i] == -1)
continue;
count++;//count计数 3为一次
if (count == n) {
kids[i] = -1;
count = 0;
reminder--;
}
}
return getWinner();
}
private static int getWinner() {
int winner = -1;
for (int i = 0; i < kids.length; i++) {
if (kids[i] != -1) {
winner = kids[i];
break;
}
}
return winner;
}
private static void disp(int winner) {
System.out.println("获胜者编号:" + winner);
}
}
第二种:ArrayList类
/**
* 使用ArrayList求解约瑟夫环问题
* @author OnTheRoad_
*/
import java.util.ArrayList;
public class JoseCircle3 {
private static int totalNum = 10;
private static int m = 3;//m表示报的数
private static ArrayList<Integer> list;
public static void main(String[] args) {
init();//初始化
int winner = solve();//模拟过程
disp(winner);
}
private static void init() {
list = new ArrayList<>();
for (int i = 0; i < totalNum; i++) {
list.add(i);
}
}
private static int solve() {
int remainNum = totalNum;
int i = -1;
while (remainNum > 1) {
i = (i + m) % list.size();
list.remove(i);
remainNum--;
}
return list.get(0)+1;//最后list里剩下的只有一个数,而这个数的序号一定为0,+1表示剩下的这个人是第几个人
}
private static void disp(int winner) {
System.out.println("胜利者的编号为:"+winner);
}
}