【面试题045】圆圈中最后剩下的数字
题目:
0, 1, ... , n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。
求出这个圆圈里剩下的最后一个数字。
思路一:
用环形链表来模拟这个圆圈。 std::list,并不是一个环形链表,因此扫描到链表末尾的时候,我们要记得把迭代器移到链表的头部。
——这种方法没删除一个数字需要m步运算,总共有n个数字,因此总的时间复杂度是O(mn),空间复杂度是O(n)。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include <iostream>
#include <list> using namespace std; 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); } int main() { cout << LastRemaining( 5, 3) << endl; return 0; } |
思路二:
找规律,映射的问题。