约瑟夫环

问题

N个人围成一圈,从一开始报数,数到K的人自动退出,然后再从一开始报数。。。依次循环直到所有人都退出

解决方案一-基于list实现

思路:将N个人排号放入list中,数到K的人从list删除,以此类推,直到list .size为零表示所有人全部退出

public static void yueSeFuByList(int peopleNum,int countNum){
        if(peopleNum<0 || countNum<=0){//参数校验,人数、计数为负时方法结束
                return;
        }
        List<Integer> list=new ArrayList<Integer>();//新建list,模拟环,并循环将人的编号赋值输入,编号从1开始
        for(int i=0;i<peopleNum;i++){
            list.add(i+1);
        }
        int index=0,count=0;//index为0,也就是第一个人开始计数;count记录排除的人数
        while(list.size()>0){//list.size()非零,表示还有人没被排除;为0表示所有人均已被排除
            index=(index+countNum-1)%list.size();//统计每次数到countNum时的人索引
            count++;//排除人数加1
            System.out.println("第"+count+"个排除的人是"+list.get(index));
            list.remove(index);//排除数到countNum的人


        }
    }

解决方案一-基于数组实现

思路:将N个人排号放进数组中,数到K的人对应值非0改成0(0表示此人已退出,非0表示未退出),直到未退出的人为0停止循环

public static void yueSeFuByArray(int peopleNum,int countNum){
        if(peopleNum<1 || countNum<1){//参数校验,人数、计数为负时方法结束
                return;
        }
        int livePeople=peopleNum,j=0,count=0;//livePeople记录为还留存的人,默认与参与人数一致;j表示数组索引;count报的数值
        int []array=new int[peopleNum];//新建数组,并循环将人员编号赋值,1表示人未被排除,0表示人已退出,即不在参与计数
        for(int i=0;i<array.length;i++){
            array[i]=1;
        }
        while (livePeople>0){//livePeople非0,表示还有人留存,需全部排除后才结束
            if(j==peopleNum){//当索引超过数组界限时,索引归0,即从头继续判断
                j=0;
            }
            if(array[j]==1){//索引对应的人为1,表示人还留存
                count++;//报数加1
                if(count==countNum){//报的数就是要排除的数,如报到3的人排除
                    array[j]=0;//该人排除
                    count=0;//报数器归0,即下次从1开始报
                    livePeople--;//留存的人减1
                    System.out.println("第"+(peopleNum-livePeople)+"个排除的是"+(j+1));
                }
            }
            j++;//索引数+1,即下次判断下一个人
        }
    }

结果验证

验证代码

@Test
    public  void test4Fun(){
        System.out.println("通过list实现");
        TestYueye.yueSeFuByList(10,3);
        System.out.println("通过数组实现");
        TestYueye.yueSeFuByArray(10,3);
    }

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值