美文网首页
约瑟夫环保存每一步弹出的值

约瑟夫环保存每一步弹出的值

作者: steamed_bun | 来源:发表于2019-10-18 11:19 被阅读0次

题目:

//每隔3个报数的移除原来的List
[1,2,3,4,5,6,7]-初始序列
[1,2,4,5,6,7] => 3被算出并进入结果[3]
[1,2,4,5,7] => 6被算出并进入结果[3,6]
[1,4,5,7] => 2被算出并进入结果[3,6,2]
[1,4,5] => 7被算出并进入结果[3,6,2,7]
[1,4] => 5被算出并进入结果[3,6,2,7,5]
[4] => 1被算出并进入结果[3,6,2,7,5,1]
[] => 4被算出并进入结果[3,6,2,7,5,1,4]

法一:将算出的值移除List,然后继续往后计算

public static void main(String[] args) {
    List<Object> items = new ArrayList<>();
    items.add(1);
    items.add(2);
    items.add(3);
    items.add(4);
    items.add(5);
    items.add(6);
    items.add(7);
    List<Object> objects = fun(items, 3);
    objects.forEach(System.out::println);
}

private static <T> List<T> fun(final List<T> items, final int k) {
    int current = 0;
   List<T> answer= new ArrayList<>();
    while (items.size() > 0) {
        current = (current-1+k)%items.size();
        answer.add(items.remove(current));
    }
    return answer;
}

法二:先计算出移除的下标值,然后直接取List中的值
计算下标值的方法来源于约瑟夫环问题递归解法的一点理解
此文章只介绍了计算最后出环的值,衍生一下就可以得出每一步出环的值
<-- 符号是可以通过公式推出值的意思
由文章可知公式是 ( 新环中的数字 + 最大报数值 )% 旧总人数
最大报数值:每隔N个报数的值

//由一般到特殊
7人环第7次出环的值 <--6人环第6次出环的值 <--5人环第5次出环的值 <--4人环第4次出环的值 <--3人环第3次出环的值 <--2人环第2次出环的值 <--1人环第1次出环的值 == 0
7人环第6次出环的值 <--6人环第5次出环的值 <--5人环第4次出环的值 <--4人环第3次出环的值 <--3人环第2次出环的值 <--2人环第=1次出环的值 == (3-1)%2
7人环第5次出环的值 <--6人环第4次出环的值 <--5人环第3次出环的值 <--4人环第2次出环的值 <--3人环第1次出环的值 == (3-1)%3
...
7人环第2次出环的值 <--6人环第1次出环的值 == (3-1)%6
7人环第1次出环的值 == (3-1)%7

这样,就只需要知道每个环第一次出环的值,就可以推算出7人环的出环的值了
而很简单可以推出,每个环第一次出环的值公式为 (最大报数值 - 1) % 总人数

public static void main(String[] args) {
    List<Object> items = new ArrayList<>();
    items.add(1);
    items.add(2);
    items.add(3);
    items.add(4);
    items.add(5);
    items.add(6);
    items.add(7);
    //保存下标值
    List<Integer> index = funTo(items.size(), 3);
    List<Object> result = new ArrayList<>(items.size());
    for (Integer integer : index) {
        result.add(items.get(integer));
    }
    result.forEach(System.out::println);
}
private static List<Integer> funTo(final int size, final int k) {
    int start;
    List<Integer> index = new ArrayList<>();
    for (int j = 1; j <= size; j++) {
        start = (k - 1) % (size - j + 1);
        for (int i = 1; i < j; i++) {
            start = (start + k) % (size - j + i + 1);
        }
        index.add(start);
    }
    return index;
}

相关文章

  • 约瑟夫环保存每一步弹出的值

    题目: 法一:将算出的值移除List,然后继续往后计算 法二:先计算出移除的下标值,然后直接取List中的值计算下...

  • 45、圆圈中最后剩下的数字

    经典的约瑟夫环问题。 当队列长度为1时,结束while循环,返回结果。 每次走m步,其中每一步都要把队首的元素添加...

  • 约瑟夫环问题

    约瑟夫环问题约瑟夫环描述:约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围...

  • 循环单链表实现约瑟夫环(C语言)

    约瑟夫环

  • 约瑟夫环

    题目:100名学生围成一个圈, 编号从1到100,从第一名学生开始报数,从1-9报数 每报出9就退出,直到所有学生...

  • 约瑟夫环

  • 约瑟夫环

    问题:1~n个人围成一圈,从1开始报数,每次数到m这个人就出列,问最后剩下的是几号? 做法:递归。 假设剩下的是f...

  • 约瑟夫环

    解法一 用一个list模拟删除过程 解法二 数学公式,推到过程还没看懂

  • 约瑟夫环

    之前去面试的时候遇到这个问题,作为一只算法渣渣,自然带着恐惧的心情,然后自己瞎捣鼓了好长时间终于拼凑出来了一个很菜...

  • 约瑟夫环

网友评论

      本文标题:约瑟夫环保存每一步弹出的值

      本文链接:https://www.haomeiwen.com/subject/vvmvmctx.html