约瑟夫环问题描述
N个人排成圈,从1-N编号。从1号开始报数,每次报M的人自杀。下一人重新从一号开始报数,依然是报M的人自杀。问最后存活下来的M-1人的编号。(M<N)
解题思路
- 创建一个链表s,添加1-N个人的编号,设i为要自杀的人的下标
- 则第一名自杀者的下标i为M-1,s移出该节点。此时链表M-N节点前移一位。
- 计算第二位自杀者下标为i=i(上一次:i=M-1)+M-1,为了实现按环循环删除,对上式取模。i=(i+M-1)%(此时链表的长度)
- 重复上述过程,直到链表最后长度等于M-1.
代码实现
public class Joseph{
//输出每次自杀者的编号
public static void suicide(List<Integer> s,int M){
int i=M-1;
while(s.size()>M-1){
System.out.println("自杀者编号:"+s.get(i));
s.remove(i);
i=(i+M-1)%s.size;
}
}
public static void main(String[] args){
ArrayList<Integer> s=new ArrayList<Integer>();
int k=3;//报3的人自杀,所以最后剩余2人
//向链表中加入41人
for(int i=1;i<42;i++){
s.add(i);
}
suicide(s,k);
//输出链表中剩余两人的编号
System.out.println("存活下来的"+(k-1)+“人的编号:”)
s.forEach(System.out::println);
}
}
运行结果

本文详细解析了约瑟夫环问题,通过链表实现算法,展示了如何在N个人的环形队伍中,找到特定条件下最后存活的M-1个人的编号。提供了完整的代码示例及运行结果。
934

被折叠的 条评论
为什么被折叠?



