面试算法(四十五)圆圈中最后剩下的数字

来源:互联网 发布:java ssl 单向认证 编辑:程序博客网 时间:2024/05/16 17:59

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

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


解法一:用环形链表模拟圆圈

创建一个总共有n个结点的环形链表,然后,每次在这个链表中删除第m个结点。

我们可以用模板库中std::list来模拟一个环形链表。由于其本身并不是一个环形结构,因此每当迭代器扫描到链表末尾的时候,要记得把迭代器移到链表的头部,这就相当于按照顺序在一个圆圈里遍历了。

int LastRemaining(unsigned int n, unsigned int m){if(n<1 || m<1)return -1;unsigned int i = 0;list<int> numbers;for(i=0; i<n; ++i)numbers.push_back(i);list<int>::iterator current = numbers.begin();while(numbers.size() > 1){for(int i=1; i<m; ++i){current++;if(current == numbers.end())current = numbers.begin();}list<int>::iterator next = ++ current;if(next == numbers.end())next = numbers.begin();--current;numbers.erase(current);current = next;}return *(current);}


解法二:

定义一个关于n和m的方程f(n,m),表示每次在n个数字0,1,....,n-1中每次删除第m个数字最后剩下的数字。

int LastRemaining(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;}


0 0
原创粉丝点击