3.约瑟夫环
问题描述
约瑟夫环问题是这样的:
0,1,…,n−1 这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。
解题思路
从后往前依次推导,
最后只剩下1个数字,它在位置pos=0。
倒数第二轮,只剩下2个数字,最后剩下的数字的位置pos=(0+m)%2
倒数第三轮,只剩下3个数字,最后剩下的数字的位置pos=((0+m)%2+m)%3
......
这样第一轮它所在的位置就能推导出来,就是我们要求的。
(数学证明略)
class Solution(object):
def findTheNumber(self, n, m):
pos = 0
for i in range(2,n+1):
pos = (pos + m) % i
return pos
例题
力扣1823
# 1.使用数学迭代,就是上面的那个模板
# 时间O(n) 空间O(1)
class Solution(object):
def findTheWinner(self, n, k):
pos = 0
for i in range(2, n + 1):
pos = (pos + k) % i
return pos + 1
# 2.使用队列
# 时间O(nk) 空间O(n)
class Solution:
def findTheWinner(self, n: int, k: int) -> int:
q = deque(range(1, n + 1))
while len(q) > 1:
for _ in range(k - 1):
q.append(q.popleft())
q.popleft()
return q[0]
# 3.本人一时脑热的集合版本
class Solution:
def findTheWinner(self, n: int, k: int) -> int:
index=0
a=[]
a=set(a)
for i in range(n):
a.add(i+1)
i=1
while i<=n:
if len(a)==1:
a=list(a)
return a[0]
if i in a:
index+=1
if(index==k):
a.remove(i)
index=0
i+=1
i=i%(n+1)
if(i==0):
i=1
Comments NOTHING