思路分析
这是很经典一个模拟的题目,约瑟夫环.
队列模拟
每次取出队首的元素看看,如果不用删除则放在队尾,如果要删除就是删除,最后队列剩下一个元素就停止操作.
cpp
class Solution {
public:
int lastRemaining(int n, int m){
queue<int> q;
for(int i=0;i<n;i++)
q.push(i);
int cnt = 0;
while(q.size()!=1){
cnt = (cnt+1)%m;
if(cnt!=0)
q.push(q.front());
q.pop();
}
return q.front();
}
};
python
class Solution(object):
def lastRemaining(self, n, m):
"""
:type n: int
:type m: int
:rtype: int
"""
from queue import deque
q = deque()
for i in range(n):
q.append(i)
cnt = 0
while len(q)>1:
cnt = (cnt+1)%m
if cnt!=0:
q.append(q[0])
q.popleft()
return q[0]
数学
但是使用模拟的方法,在力扣上不能AC的!
所以这里要使用数学的推到方式.
f(n,m)=m-1
f(n-1,m)=(m+m)%n
...
f(n,m)=(f(n-1,m)+m)%n
边界:
if(n==1)return 0;
如何考虑呢? 如果只有一个人,那么就直接放回自己即可
cpp
class Solution {
public:
int lastRemaining(int n, int m) {
if(n==1)return 0;
return (lastRemaining(n-1,m)+m)%n;
}
};
python
class Solution:
def lastRemaining(self, n: int, m: int) -> int:
if n==1: return 0
return (self.lastRemaining(n-1,m)+m)%n