@ 剑指offer(python)孩子们的游戏(圆圈中最后剩下的数)

剑指offer刷题笔记46(python)

题目描述

每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数…这样下去…直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!_)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)

思路1

利用一个数组来模拟这个过程,不断从数组中删除已经元素,直到数组中剩下最后一个元素。不过这种做法的时间复杂度很高,o(nm),当数很多的时候,效率不是很好

代码1

# -*- coding:utf-8 -*-
class Solution:
    def LastRemaining_Solution(self, n, m):
        # write code here
        if n < 1:
            return -1
        start = 0   # 设置每次报数的起始位置,不断更新
        final = -1  # 每次唱歌的小朋友的编号,初始化为-1,也不断更新,final的最后取值就是最后一个小朋友的编号
        indexlist = range(n)
        while indexlist :
            k = (start + m - 1) % n
            n -= 1
            final = con.pop(k)
            start = k   # 因为把第k个给删除了,从原来的k+1个,删除之后的第k个开始。
        return final 

思路2

找出这个过程的递推公式。
@ 剑指offer(python)孩子们的游戏(圆圈中最后剩下的数)_第1张图片
其中,f(n,m)表示有n人,指定数为m的最后胜利者的位置。
其详细推导过程见何海涛老师的博客:http://zhedahht.blog.163.com/blog/static/2541117420072250322938/

要注意的是,牛客给了一个超大的数,会显示递归maximum recursion depth exceeded,这是需要引入一个sys库,来修改递归深度

代码2

# -*- coding:utf-8 -*-
import sys
sys.setrecursionlimit(1000000)
class Solution:
    def LastRemaining_Solution(self, n, m):
        # write code here
        if n == 0:
            return -1
        if n == 1:
            return 0
        return (self.LastRemaining_Solution(n-1,m) + m ) % n

你可能感兴趣的:(剑指offer(python),剑指offer(python))