0
点赞
收藏
分享

微信扫一扫

剑指offer 62. 圆圈中剩下的数字(约瑟夫环问题)

泠之屋 2022-04-18 阅读 52

剑指 Offer 62. 圆圈中最后剩下的数字 - 力扣(LeetCode) (leetcode-cn.com)

目录

运行结果

分析

删除第m个数字

序列重组

映射

递推关系

代码


运行结果

 

分析

删除第m个数字

初始序列:

0, 1, ..., n-1    (1)

我们把从序列(1)中按照规则不断删除第m个数字 最后剩下的数字记作f(n, m)

进行一次操作,我们删除掉的数字:k = (m-1)%n

剩余的序列:0, 1, ..., k-1, k+1, ..., n-1

序列重组

按照规则,下次从k+1开始计数,于是我们把该序列重组,得到:

k+1, ..., n-1, 0, 1, ..., k-1    (2)

该序列可以看作是把以下序列整体 % n 之后得到的序列
k+1, ..., n-1, n, n+1, ..., n+k-1

序列(2)有n-1项,我们把从该序列中不断按照规则删除第m个数字之后剩下的数字记作g(n-1, m)则:

f(n, m) == g(n-1, m)

映射

我们对序列(2)做一个映射,得到序列(3):

k+1    ->    0
...
n-1    ->    n-k-2
0      ->    n    ->    n-k-1
...
k-1    ->    n+k-1    ->    n-2


0,1,...,n-2    (3)

我们把这种映射记作p(x),则p(x) = (x - k - 1) % n

该映射的逆映射为:q(x) = (x + k + 1) % n

序列(3)有n-1项,且和序列(1)具有同样的形式,因此从序列(3)中按照规则不断删除第m个元素后剩下的数字为 f(n-1, m)

根据序列(2)和序列(3)之间的映射关系,我们可以得出:

g(n-1, m) == q( f(n-1, m) )

那么就有:

f(n, m) == q( f(n-1, m) )

因此我们就得到了:

递推关系

f(n, m)
= q( f(n-1, m) )
= ( f(n-1, m) + k + 1 ) % n
= ( f(n-1, m) + (m-1)%n + 1 ) % n
= ( f(n-1, m) + m ) % n

如果初始序列中只有一个元素0,那么按照规则,0就是最终剩余的元素,即:

f(1, m) = 0

根据递推关系,即可写出代码

代码

class Solution {
public:
	int lastRemaining(int n, int m) {
		int last = 0;
		for (int i = 2; i <= n; ++i) {
			last = (last + m) % i;
		}
		return last;
	}
};
举报

相关推荐

剑指offer--数组中重复的数字

0 条评论