python 列表切片解决约瑟夫环问题

约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依规律重复下去,直到圆桌周围的人全部出列

前几天笔试的时候遇到过这个问题,求出最后一个出列的数,

想了一个很简单的列表切片方式解决,

在和面试官讲解了思路后,被歧视了。。。。。说是没这么简单,回来后倒腾出来了

基本思路:

假设n=5:list=[1,2,3,4,5]

,m=3:key=m-1

一次循环,以k作为锚点,对list进行切片,切成两个:

list1 = [1,2],list2= [4,5]

然后再合并,形成一个新的list = list2+list1

此时,list = [4,5,1,2]

重复该步骤,当len(list)==1时,弹出list[0]

ok,思路没问题,这部分要注意的是,当n<m,n<m-n,n=m,n>m时,所执行的切片部分略有不同

def ysf(n,m):
    list = [x for x in range(1,n+1)]
    key = m-1
    /如果n或m等于1.直接返回列表的最后一位
    if n == 1 or m == 1:
        return list[-1]
    
    while True:
        /当m<列表长度,直接切片
        if m < len(list):
            print(list[key])
            list = list[key+1:] + list[:key]
            print(list)
        /当m=列表长度,去掉列表的最后一位
        if m == len(list):
            list.pop(-1)
            print(list)

        if m > len(list):

            if len(list) == 1:
                return list[0]
            /当 m>m-len(list),执行循环语句一直减去len(list),直到m小于列表长度
            s = m-len(list)
            while s > len(list):
                s-=len(list)

            list = list[s:] + list[:s-1]
            print(list)


n,m = 3,10
print(ysf(m,n))

最后执行结果:

3
[4, 5, 6, 7, 8, 9, 10, 1, 2]
6
[7, 8, 9, 10, 1, 2, 4, 5]
9
[10, 1, 2, 4, 5, 7, 8]
2
[4, 5, 7, 8, 10, 1]
7
[8, 10, 1, 4, 5]
1
[4, 5, 8, 10]
8
[10, 4, 5]
[10, 4]
[4]
4

总的来讲。。。这好像是用到了归并的思路?

 

转载于:https://my.oschina.net/u/3731979/blog/1577248

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值