约瑟夫环问题:有n个人围成一圈,顺序编号。从第1个人开始报数(从1-3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位?

整体逻辑:

  1. 先标记数到3的人

  1. 截取末尾不够数到3的人,他们将是下次报数的开始

  1. 过滤标记的人,也就是把报3的删除

  1. 将截取的人拼到数组的最前面 ,记得数组末尾要删除他们

  1. 拼接好的数组继续执行上述操作,直到数组长度为3,也就是递归到出口

  1. 递归出口:当2人或者3人报数时,结果是固定的,都是2号位留下

代码如下:

let arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']

    function fn(arr) {
        //当数组最后长度为3时,结果就可以直接输出了
        if (arr.length <= 3) {
            return arr[1]
        }
        //遍历数组,将报到3的人做标记,让它为0
        for (let i = 0; i < arr.length; i++) {
        //数组下标是从0开始的,但是报数是从1开始的,所以这里要下标加1,再取余
            if ((i + 1) % 3 == 0) {
                arr[i] = 0
            }
        }
        //筛选所有不为0的人为新数组
        let newarr = arr.filter((v) => v != 0)
        // 截取原数组报到最后一个0后,还剩几个人 arr.slice(-(arr.length % 3))
        //新数组  删除我们截取的数组(或者说截取我们需要的部分)
        newarr = newarr.slice(0, newarr.length - (arr.length % 3))
        //将截取的数组 合并 到新数组的前边

        //合并后的结果作为参数,进行递归
        return fn(arr.slice(-(arr.length % 3)).concat(newarr))

    }
    //输出最后剩余的谁
    console.log(fn(arr));
    //输出剩余的原来的几号
    console.log(arr.indexOf(fn(arr)) + 1);

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
约瑟夫题是一个古老且著名的题,它描述了n个人围成一圈,从第一个人开始报数,每次报到第m个人,这个人将被杀掉,直到最后只剩下一个人。 这个题可以通过模拟来解答。首先,我们创建一个包含n个人的循环链表,每个节点表示一个人。然后,我们从第一个人开始,按顺序数m个人,直到找到第m个人。然后,我们将这个人从链表中移除,再次从移除的下一个人开始,继续数m个人,一直重复这个过程,直到链表中只剩下一个人。 为了更好地理解,我们可以用一个具体的例子来说明。假设有5个人编号为1,2,3,4,5)围成一圈,从第一个人开始报数,第3个人将被杀掉。 首先,我们从第一个人开始,数1,2,3,第3个人编号为3的人,将其移除。现在剩下4个人:1,2,4,5。接下来,我们从编号为4的人开始,数1,2,3,第3个人编号为2的人,将其移除。现在剩下3个人:1,4,5。我们继续从编号为4的人开始,数1,2,3,第3个人编号为5的人,将其移除。现在剩下2个人:1,4。我们再次从编号为1的人开始,数1,2,3,第3个人编号为1的人,将其移除。最后,只剩下编号为4的人,他是幸存者。 总结来说,约瑟夫题是一个经典的数学题,可以通过模拟来解答。每次从围成一圈的人中按顺序数m个人,将第m个人移除,最后只剩下一个人。这个题具有一定的实际意义,也可以帮助我们理解和运用数学模型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暮暮最后的倔强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值