leetcode 圆圈中最后剩下的数字(约瑟夫环)

关注公众号 长歌大腿,发送“机器学习”关键字,可获取包含机器学习(包含深度学习),统计概率,优化算法等系列文本与视频经典资料,如《ESL》《PRML》《MLAPP》等。

题目描述:

0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。

例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

示例 1:

输入: n = 5, m = 3
输出: 3
示例 2:

输入: n = 10, m = 17
输出: 2

限制:

1 <= n <= 10^5
1 <= m <= 10^6

解题思路:

根据题目描述,这是一个典型的约瑟夫环问题,如果用模拟方法来求解,则复杂度为 O ( m n ) O(mn) O(mn)的时间复杂度。在m,n很大时不可接受。
我们观察得到,当还有J个数字时,删除该时候的第m个数字,剩下的数字在进行下一次报数过程中下角标从删除数字的位置开始,老序列下角标为 p j p_{j} pj的话则新序列的下角标为 p j + 1 − m p_{j+1}-m pj+1m(在同余类的表示情况),其中p为上次的下角标。故,反过来,假设已知新序列的下角标为 p i + 1 p_{i+1} pi+1,则上一次序列的角标为 p i + m p_{i}+m pi+m,其递推关系式可写为:
F ( n , m ) = ( F ( n − 1 , m ) + m ) % n F(n,m) = (F(n-1,m)+m)\%n F(n,m)=(F(n1,m)+m)%n

代码实现(Java):

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

实现分析:

实现算法复杂度为O(n)。

你可能感兴趣的:(leetcode)