经典面试题:n个数字(0,1,…,n-1)形成一个圆圈


题目:

n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始, 
每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。 
当一个数字删除后,从被删除数字的下一个继续删除第m个数字。 
求出在这个圆圈中剩下的最后一个数字。 

 

我的思路:

这是个很经典的环形问题,最优的方案时间复杂度是O(n):先构建递推公式,再使用循环或者递归都能轻松求解,

网上的教程很少能把这个递推公式的由来描述清楚,所以我在这里加入我的一些理解。

由于我们要求解的是n个元素,第m个数字,要找到最后的一个数字,那么我在这里假设得到的结果是f(n,m),

假设我们已有数列为:

0    1    ...  m-2    m-1  m  ...     n-1

删除一次后得到的新数列是(注意题目条件->从被删除数字的下一个继续删除):

m    m+1   ...   n-1     0    1    ...    m-2   ①

很显然,通过一次删除后,问题规模从n变成了n-1,而f(n-1,m)所要求解的数列是:

0    1    ...  m-2    m-1  m  ...     n-2 ②

很显然,把数列②向左移动m就变成了①的解(注意①和②不完全相同,但是我们想要求的是第一个值,因为第一个值是删除后剩下的数字),

考虑到“左加右减”的数学原理和环形的特征,得到递推公式:

               0                          if n==1  

f(n,m)={                                            

               (f(n-1,m)+m)%n    if  n>1

那么也就不难得到如下代码:

int LastNumberOfCircle(int n, int m)
{
    int last = 0;
    for(int i=2;i<=n;++i)
    {
        last = (last+m)%i;
    }
    return last;
}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



猜您在找 面试题3:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。 面试题:f(n) = f(n-1) + f(n-2) 求 f(100) 面试题:给定一个长度为N的数组,其中每个元素的取值范围都是1到N。判断数组中是否有重复的数字 【面试题043】n个骰子的点数 求Sn=1!+2!+3!+4!+5!+…+n!之值,其中n是一个数字 LeetCode–0~n-1中缺失的数字 初学者习题练习。从控制台输入一个数n,使用for循环实现求n! 提示:n! =n*(n-1)*(n-2)*…*1 升级:求1!+2!+3!+…+n!的值 剑指Offer(Java版)第五十六题:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。 也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM