约瑟夫环

题目示例: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());
    }

参考:http://bbs.csdn.net/topics/340031949

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值