【剑指offer系列】 圆圈中最后剩下的数字___45

  题目描述:
  把0 ,1 ,……, n-1这n个数排成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字。
  求这个圆圈剩下的最后一个数字
  
  示例:
  输入:n=3,m=2,即把0 ,1 ,2这三个数字每次删除第二个,删除的依次为1, 0,剩下2
  输出:2
  
  分析:
  经典解法,用环形链表模拟圆圈。当链表中只有一个节点时,退出。但是这种方法空间复杂度较高
  【剑指offer系列】 圆圈中最后剩下的数字___45_第1张图片 
  
  更高效的解法,分析其中的数学规律。
  在n个数字中,第一个被删除的是 k = (m-1)%n
  在删除k个,剩下的n-1个数字为:0, 1 ,…… ,k-1 ,k+1 , ……, n-1
  然后新一轮的计数从k+1开始,即k+1为第一个数字,形成 k+1 , …… ,n-1 ,0 , 1 ,…… k-1。剩下的数字也是n和m的函数。
  将剩下的n-1个数字作一个映射:
  【剑指offer系列】 圆圈中最后剩下的数字___45_第2张图片
  将映射定义为p,则p(x) = (x-k-1)%n。该映射的逆映射为f(x)=(x+k+1)%n。
  映射后的序列和最初的序列具有相同的形式,只是元素个数变为了n-1.
  因此可得到递推公式:
  这里写图片描述
  
  代码:    

int lastRemain(unsigned int n,unsigned int m){
    if(n<1||m<1)  return -1;
    int last=0;
    for(int i=2;i<=n;++i){
        last=(last+m)%i;
    }
    return last;
}

你可能感兴趣的:(剑指offer)