微软算法100道题

原创 2015年11月20日 16:10:42

题目:

n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,

每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。
当一个数字删除后,从被删除数字的下一个继续删除第m个数字。

求出在这个圆圈中剩下的最后一个数字。


思路:

这道题的思路。。。委屈  我是没有思路,感觉得用得到数学公式之类的东西,所以上网查了一下:

分析:既然题目有一个数字圆圈,很自然的想法是我们用一个数据结构来模拟这个圆圈。在常用的数据结构中,我们很容易想到用环形列表。我们可以创建一个总共有m个数字的环形列表,然后每次从这个列表中删除第m个元素。 
在参考代码中,我们用STL中std::list来模拟这个环形列表。由于list并不是一个环形的结构,因此每次跌代器扫描到列表末尾的时候,要记得把跌代器移到列表的头部。这样就是按照一个圆圈的顺序来遍历这个列表了。 
这种思路需要一个有n个结点的环形列表来模拟这个删除的过程,因此内存开销为O(n)。而且这种方法每删除一个数字需要m步运算,总共有n个数字,因此总的时间复杂度是O(mn)。当m和n都很大的时候,这种方法是很慢的。 
接下来我们试着从数学上分析出一些规律。首先定义最初的n个数字(0,1,…,n-1)中最后剩下的数字是关于n和m的方程为f(n,m)。 
在这n个数字中,第一个被删除的数字是m%n-1,为简单起见记为k。那么删除k之后的剩下n-1的数字为0,1,…,k-1,k+1,…,n-1,并且下一个开始计数的数字是k+1。相当于在剩下的序列中,k+1排到最前面,从而形成序列k+1,…,n-1,0,…k-1。该序列最后剩下的数字也应该是关于n和m的函数。由于这个序列的规律和前面最初的序列不一样(最初的序列是从0开始的连续序列),因此该函数不同于前面函数,记为f’(n-1,m)。最初序列最后剩下的数字f(n,m)一定是剩下序列的最后剩下数字f’(n-1,m),所以f(n,m)=f’(n-1,m)。 
接下来我们把剩下的的这n-1个数字的序列k+1,…,n-1,0,…k-1作一个映射,映射的结果是形成一个从0到n-2的序列: 
k+1     ->     0 
k+2     ->     1 
… 
n-1     ->     n-k-2 
0    ->     n-k-1 
… 
k-1    ->    n-2 
把映射定义为p,则p(x)= (x-k-1)%n,即如果映射前的数字是x,则映射后的数字是(x-k-1)%n。对应的逆映射是p-1(x)=(x+k+1)%n。 
由于映射之后的序列和最初的序列有同样的形式,都是从0开始的连续序列,因此仍然可以用函数f来表示,记为f(n-1,m)。根据我们的映射规则,映射之前的序列最后剩下的数字f’(n-1,m)= p-1 [f(n-1,m)]=[f(n-1,m)+k+1]%n。把k=m%n-1代入得到f(n,m)=f’(n-1,m)=[f(n-1,m)+m]%n。 
经过上面复杂的分析,我们终于找到一个递归的公式。要得到n个数字的序列的最后剩下的数字,只需要得到n-1个数字的序列的最后剩下的数字,并可以依此类推。当n=1时,也就是序列中开始只有一个数字0,那么很显然最后剩下的数字就是0。我们把这种关系表示为: 
          0                   n=1 
f(n,m)={ 
          [f(n-1,m)+m]%n      n>1 


然后就按这个公式写。。。。

版权声明:本文为博主原创文章,未经博主允许不得转载。

微软经典面试100题系列(部分)

本文整理自:http://blog.csdn.net/v_july_v/article/details/6543438     1. 把二元查找树转变成排序的双向链表     题目: 输入一棵二元查...
  • zhoudaxia
  • zhoudaxia
  • 2014年07月10日 14:29
  • 16439

微软等数据结构+算法面试100题全部答案集锦

1.把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。 10 / \ 6 14 / \ ...
  • lipengshiwo
  • lipengshiwo
  • 2016年11月26日 17:28
  • 3407

2017微软面试算法题回顾

惨痛的回忆= = 1.求一个数组中的逆序对数 思路:O(n2)的解法很明显,暴力破解即可。但这肯定不是面试官要的答案,很明显这样的题是找至少O(nlogn)的解法。 考虑使用归并...
  • dreamerleague
  • dreamerleague
  • 2017年04月25日 12:15
  • 393

微软算法面试题带答案

  • 2016年12月16日 14:08
  • 370KB
  • 下载

微软等数据结构+算法面试100题全部答案集锦

微软等数据结构+算法面试100题全部答案集锦 作者:July、阿财。 时间:二零一一年十月十三日。 引言      无私分享造就开源的辉煌。      今是二零一一年十月十三...
  • GarfieldEr007
  • GarfieldEr007
  • 2015年10月06日 14:04
  • 5667

微软等数据结构+算法面试100题全部答案集锦

作者:July、阿财。 时间:二零一一年十月十三日。  引言      无私分享造就开源的辉煌。      今是二零一一年十月十三日,明日14日即是本人刚好开博一周年。在一...
  • idaretobe
  • idaretobe
  • 2015年01月13日 20:50
  • 1852

微软等数据结构+算法面试100题全部答案集锦

  • 2015年01月26日 14:26
  • 370KB
  • 下载

微软算法问题全集

1,求子数组的最大和 题目: 输入一个整形数组,数组里有正数也有负数。 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。 求所有子数组的和的最大值。要求时间复杂度为O(n)。 例如输入...
  • gexiaobaoHelloWorld
  • gexiaobaoHelloWorld
  • 2014年10月22日 10:08
  • 694

微软100题算法解答

本文是旨在实践”用变量、循环
  • binling
  • binling
  • 2014年05月14日 00:06
  • 625

微软等公司数据结构+算法面试100题、分析、考点、解答(第1~100题)

1.把二元查找树转变成排序的双向链表  题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。    10  / \  6 14...
  • huangxiaominglipeng
  • huangxiaominglipeng
  • 2014年10月27日 01:27
  • 1512
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:微软算法100道题
举报原因:
原因补充:

(最多只允许输入30个字)