面试遇到的算法题(约瑟夫环)

本人比较小白,前几天面试遇到了一道算法题,因为之前没怎么看过算法题,所以当时没做出来,当然面试也凉了,回来查了一些资料,把题目搞明白了,在这里整理一下.

python 实现:题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

解题思路

当人数恰好是3的倍数时,剔除报数中3的倍数的人员编号。
但是总人数不为3的倍数时,需要把最后剩下的1个或者2个人取出来,放到剔除3倍数后人员编号的最前面(从新一次报数,这样模拟围城一个圈的效果)。
通过while循环不断重复以上操作,直到剩余人数为2,剩下的人员编号即最后留下2个数第二个(报三次数,第1个数为3因此去掉)。

代码实现

def test(m):
    list_one = list(range(1, m + 1))
    while len(list_one) > 2:
        # 总人数恰好是3的倍数
        c = len(list_one) % 3
        list_two = []
        if c == 0:
            for i in range(1, len(list_one) + 1):
                # 将报到3的人去除,放入新列表
                if i % 3 != 0:
                    list_two.append(list_one[i - 1])
            list_one = list_two
            print(list_one)
        else:
            # 总人数不为3的倍数时,需要把最后剩下的1个或者2个人取出来,
            # 放到剔除3倍数后人员编号的最前面
            for i in range(1, len(list_one) + 1):
                # 将报到3的人去除,放入新列表
                if i % 3 != 0:
                    list_two.append(list_one[i - 1])
            # 反向切片将最后余下的人放在剔除3倍数后人员编号的最前面形成新队列
            list_one = list_two[-c:] + list_two[:-c]
            print(list_two)
            print(list_one)
    print(list_one)
    print("最后剩下人的原始编号为:{}".format(list_one[1]))


count = int(input("请输入具体人数:"))
test(count)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值