孩子们的游戏(圆圈中最后剩下的数)
2017-04-19 15:15
363 查看
题目描述
首先,让小朋友们围成一个大圈。然后随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数….这样下去….直到剩下最后一个小朋友获得神秘大奖,。请你试着想下,哪个小朋友会得到这份神秘大奖呢呢?(注:小朋友的编号是从0到n-1)题解
解法1
模拟环形链表这里通过取模运算直接算出要删除的位置,简化了寻找的过程
class Solution { public: int LastRemaining_Solution(int n, int m) { if(n == 0) return -1; //初始化小朋友们 vector<int> haha; for(int i = 0; i < n; i++){ haha.push_back(i); } //进行游戏 int i = 0; //上次删除的位置 while(haha.size() > 1){ i = (i + m - 1) % haha.size(); haha.erase(haha.begin() + i); } return *haha.begin(); } };
解法2
定义f(n, m) 表示每次在0到i-1中删除第m个数最后剩下的数。第一次编号为 k = (m-1)%n 的小朋友出列之后,剩下的n-1个人组成了一个新的约瑟夫环:
k k+1 k+2 … n-2, n-1, 0, 1, 2, … k-2并且从k开始报0。
由于这个序列的规律与之前的不一样,记为f’(n-1,m),值与f(n,m)相同。
现在我们把他们的编号做一下转换:
k+1 --> 0 k+2 --> 1 ... ... k-2 --> n-3 k-1 --> n-2
变换后成为了 n-1 个人报数的子问题,其结果为f(n-1,m), 根据映射可求出
f’(n-1,m) = ( f(n-1,m) + k + 1) % n
代入 k = (m-1) % n,
f(n,m) = f’(n-1, m) = ( f(n-1,m) + m) % n。
最终得到递归公式为
f(1, m) = 0; //终止条件 f(i, m) = (f(i-1,m) + m) % i; //i>1
代码可选择递归或循环
class Solution { public: int LastRemaining_Solution(int n, int m) { if(n == 0) return -1; int res = 0; for(int i = 2; i <= n; i++){ res = (res + m) % i; } return res; } };
相关文章推荐
- 46孩子们的游戏(圆圈中最后剩下的数)
- 【追求进步】孩子们的游戏(圆圈中最后剩下的数)【百度阿里面试常考算法之一】
- 九度_题目1356:孩子们的游戏(圆圈中最后剩下的数)
- 【剑指offer-解题系列(47)】孩子们的游戏(圆圈中最后剩下的数)
- 剑指Offer - 九度1356 - 孩子们的游戏(圆圈中最后剩下的数)
- 剑指offer——面试题45:圆圈中最后剩下的数字(孩子们的游戏)
- 剑指Offer——孩子们的游戏(圆圈中最后剩下的数)
- 孩子们的游戏(圆圈中最后剩下的数)
- 剑指offer--(12)孩子们的游戏(圆圈中最后剩下的数)--Java描述
- 孩子们的游戏(圆圈中最后剩下的数)
- 孩子们的游戏(圆圈中最后剩下的数)
- 剑指offer:孩子们的游戏(圆圈中最后剩下的数)
- 《剑指offer》-孩子们的游戏(圆圈中最后剩下的数)
- 约瑟夫环——孩子们的游戏(圆圈中最后剩下的数)
- 牛客网剑指offer-孩子们的游戏(圆圈中最后剩下的数)
- 剑指offer:孩子们的游戏(圆圈中最后剩下的数)
- 孩子们的游戏(圆圈中最后剩下的数)
- 剑指Offer: 孩子们的游戏(圆圈中最后剩下的数)
- 题目30:孩子们的游戏(圆圈中最后剩下的数)
- 剑指offer:孩子们的游戏(圆圈中最后剩下的数)