剑指offer圆圈中最后剩下的数字 和 迭代器总结
迭代器只有++ ,--,==,!=四种运算方法,不能将iter = iteration+ 1,因为迭代器是指针类型,1是整数类型,不能直接相加赋值给一个指针。
题目描述
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)
思路;每次结束后都必须从删除的下一个元素开始,记得审题要仔细。
解法1:使用环形链表模拟圆圈,使用环形链表,每次查找到最后一个元素时,都必须将迭代器返回到begin位置。
解法2:f(n,m)表示在n个数字中,删除第m 个数字最后剩下的数字。
f(n,m) = 0,n == 1;
[f(n - 1,m) + m] %n,n > 1;
//超时牛客不能通过 class Solution { public: int LastRemaining_Solution(int n, int m){ if(n == 1){ return 0; } if(n == 0){ return -1; } list<int> num; for(int i = 0;i < n;++i){//存储节点 num.push_back(i); } list<int>::iterator iter = num.begin(); while(num.size() > 1){ for(int i = 1;i < m;++i){//找到指定节点 ++iter; if(iter == num.end()){ iter = num.begin(); } } ++iter; list<int>::iterator next = iter;//保存下一节点 if(next == num.end()){ next = num.begin(); } num.erase(--iter);//删除找到的节点 iter = next; } return *iter; } };
解法2:
class Solution { public: int LastRemaining_Solution(int n, int m){ if(n < 1 ||m < 1){ return -1; } int last = 0; for(int i = 1;i <= n;++i){ last = (last + m) % i; } return last; } };