0
点赞
收藏
分享

微信扫一扫

1823.找出游戏的获胜者

爱薇Ivy趣闻 2022-05-04 阅读 26

题目描述

解题思路

        看到这题时,我的思路是一种比较笨的方法,就是用一个布尔类型的flag数组,标记每一个人的状态,初始时每个人都为True,当在第一轮游戏中被选中时,将这个人对应位置处的flag标记为False,表示这个人失败了,因为标记为失败之后,就可以在后续的遍历中,通过该标记位知道这个人已经从游戏中退出,可以看作逻辑删除这名玩家,就可以跳过这个人,进而寻找顺时针k个位置的下个失败者,直到游戏只有一个人存在时,start中记录的即为获胜者的编号。

        实现起来,时间复杂度非常的高,达到了O(nk)量级,因为对每一个人,都要进行k步的模拟寻找下一个符合条件的失败者。这种方法不仅时间复杂度高,而且数组的下标很容易出现越界,改了三次才成功通过,最后的用时1800+ms属实是让我蚌埠住了。

        参考题解之后,我发现大可不必如此大费周章的遍历,寻找失败者,只要动态的更新玩家数组就可以了。用一个数组存储1-n名玩家的编号,start=0初始位置,更新时loser=(start+k-1)%len(ans),表示失败者的位置,另外还要更新下一轮游戏起始者的位置start=loser if loser!=len(ans)-1  else 0,就是说如果当前轮求出的失败者不是位于所剩玩家数组的最后一个,就让起始位置为刚才求出的失败者的位置,因为要接下来要删除改位置处的失败者,相当于让失败者后一个人当下轮游戏的开始者,但如果失败者已经是当前数组的最后一人,那么由于求余的性质,肯定是下标为0的人是当前失败者的后一个人,就让下轮游戏的开始者为0即可,做完以上两步更新操作后,就可以放心的把当前求出的本轮游戏失败者从玩家数组中删除了。删除之后动态的维护这个玩家数组,每轮游戏失去一个失败者,直到最后数组中只有一人时,就是要求的答案。

代码实现

1.我的实现思路:模拟依次遍历

class Solution:
    def findTheWinner(self, n: int, k: int) -> int:
        flag=[True for i in range(n+1)]
        round=1
        start=1
        while round<n:
            i=1
            while i<k :
                if flag[start%n+1]:
                    i+=1
                start=start%n+1
            flag[start]=False
            while flag[start]==False:
                start=start%n+1
            round+=1
        return start

2.参考的思路:直接计算

class Solution:
    def findTheWinner(self, n: int, k: int) -> int:
        start,ans=0,[i for i in range(1,n+1)]
        while len(ans)>1:
            loser=(start+k-1)%len(ans)
            start=loser if loser!=len(ans)-1 else 0
            del ans[loser]
        return ans[0]
举报

相关推荐

0 条评论