[LeetCode] 390. Elimination Game 淘汰游戏
There is a list of sorted integers from 1 to n. Starting from left to right, remove the first number and every other number afterward until you reach the end of the list.
Repeat the previous step again, but this time from right to left, remove the right most number and every other number from the remaining numbers.
We keep repeating the steps again, alternating left to right and right to left, until a single number remains.
Find the last number that remains starting with a list of length n.
Example:
Input:
n = 9,
1 2 3 4 5 6 7 8 9
2 4 6 8
2 6
6 Output:
6
这道题是 LeetCode 第二次编程比赛的题,然而博主并没有做出来,博主用的方法是那种最笨的方法,用一个数组把n个数组都存起来,然后根据循环的奇偶来决定是从左还是从右删除,结果不幸超时 TLE 了。后来通过想大神请教和上网搜索,发现这道题用递归来做很简单,用一个 bool 型变量 left2right,为 true 表示从左往右,为 false 表示从右往左遍历。当n为1时,不论从左往右还是从右往左都返回1。如果n大于1,且是从左往右的话,返回2倍的对 n/2 的从右往左的遍历;如果是从右往左的话,稍稍麻烦一些,肯定还是要对 n/2 调用递归函数的,但是要分奇偶情况,如果n为奇数,返回2倍的对 n/2 的从左往右的遍历的值;如果n为偶数,2倍的对 n/2 的从左往右的遍历的值,再减去1。具体这样的原因,博主还在研究中,也不是太清楚:
解法一:
class Solution {
public:
int lastRemaining(int n) {
return help(n, true);
}
int help(int n, bool left2right) {
if (n == ) return ;
if (left2right) {
return * help(n / , false);
} else {
return * help(n / , true) - + n % ;
}
}
};
下面这种方法相当的叼,一行就搞定了简直丧心病狂啊。第一次从左往右删除的时候,奇数都被删掉了,剩下的都是偶数。如果对所有数都除以2,那么得到一个1到 n/2 的新数列。下一次从右往左删出,那么返回的结果应该是调用递归的结果 lastRemaining(n / 2) 在数组1到 n/2 之间的镜像。何为镜像,比如 1, 2, 3, 4 这个数字,2的镜像就是3, 1的镜像是4,参见代码如下:
解法二:
class Solution {
public:
int lastRemaining(int n) {
return n == ? : * ( + n / - lastRemaining(n / ));
}
};
下面这种迭代的解法是博主请教另一位大神的方法,个人感觉也非常叼,膜拜大神中,先来看两个简单的例子:
n = 8
1 2 3 4 5 6 7 8
2 4 6 8
2 6
6
n = 7
1 2 3 4 5 6 7
2 4 6
4
如果仔细观察,可以发现从左往右删的时候,每次都是删掉第一个数字,而从右往左删的时候,则有可能删掉第一个或者第二个数字,而且每删一次,数字之间的距离会变为之前的两倍。这里要做的是每次记录当前数组的第一个数字,而且再通过观察可以看出,从右往左删时,如果剩下的数字个数是偶数个时,删掉的是第二个数字;如果是奇数个的时候,删掉的是第一个数字。总结出了上述规律,就可以写出代码如下:
解法三:
class Solution {
public:
int lastRemaining(int n) {
int step = , res = ;
while (step * <= n) {
res += step;
step *= ;
if (step * > n) break;
if ((n / step) % == ) res += step;
step *= ;
}
return res;
}
};
再来看一种论坛上的高分解法,其实这种解法的本质跟上面那种解法一样的,这里多使用了两个变量,一个是布尔型变量 left2right,表示当前的方向,为 true 表示是从左往右删;另一个是整型变量 remain,表示当前还剩下的数字个数。当 remain 大于1的时候进行循环,res 表示的是当前剩下的左数第一个数字。根据之前的分析,当从左往右删除的时候,左边第一个数字一定会被删掉;而从右往左删时,如果剩下的数字个数是偶数个时,删掉的是第二个数字;如果是奇数个的时候,删掉的是第一个数字。这样只要判断 left2right 为 true,或者 remain 是奇数的时候,res 要加上 step,也就是当前数字之间的间隔数,每删除一次,step 都要自乘以2,同时 remain 要除以2,left2right 也要变成其相反的状态,参见代码如下:
解法四:
class Solution {
public:
int lastRemaining(int n) {
bool left2right = true;
int res = , step = , remain = n;
while (remain > ) {
if (left2right || remain % == ) res += step;
remain /= ;
step *= ;
left2right = !left2right;
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/390
类似题目:
https://leetcode.com/problems/elimination-game/
https://leetcode.com/problems/elimination-game/discuss/87128/C-1-line-solution-with-explanation
https://leetcode.com/problems/elimination-game/discuss/87121/O(logN)-solution.-clear-break-down
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] 390. Elimination Game 淘汰游戏的更多相关文章
- 390 Elimination Game 淘汰游戏
详见:https://leetcode.com/problems/elimination-game/description/ C++: 方法一: class Solution { public: in ...
- [LeetCode] Elimination Game 淘汰游戏
There is a list of sorted integers from 1 to n. Starting from left to right, remove the first number ...
- [leetcode] 390 Elimination Game
很开心,自己想出来的一道题 There is a list of sorted integers from 1 to n. Starting from left to right, remove th ...
- 【LeetCode】390. Elimination Game 解题报告(Python)
[LeetCode]390. Elimination Game 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/elimina ...
- Java实现 LeetCode 390 消除游戏
390. 消除游戏 给定一个从1 到 n 排序的整数列表. 首先,从左到右,从第一个数字开始,每隔一个数字进行删除,直到列表的末尾. 第二步,在剩下的数字中,从右到左,从倒数第一个数字开始,每隔一个数 ...
- leetcode 390. 消除游戏
{20-01-29 19:22} class Solution { public int lastRemaining(int n) { return help(n); } public static ...
- 【leetcode】390. Elimination Game
题目如下: 解题思路:对于这种数字类型的题目,数字一般都会有内在的规律.不管怎么操作了多少次,本题的数组一直是一个等差数列.从[1 2 3 4 5 6 7 8 9] -> [2 4 6 8] - ...
- [LeetCode] Burst Balloons 打气球游戏
Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by ...
- [LeetCode] Game of Life 生命游戏
According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...
随机推荐
- 计算机基础 ---- 编码(er)
1.字符集与编码 字符集:字符组成的集合,汉字,字母,符号被收录到标准的字符集合 编码:规定每个字符使用一个字节还是多个字节存储,那些字节来存储的规定 术语:字符编码(character encodi ...
- centos 8 重启网络 systemctl restart network 失效的解决办法
参考: https://www.tecmint.com/set-static-ip-address-in-rhel-8/ https://www.tecmint.com/configure-netwo ...
- C#关于函数重载的坑
今天在调用被重载的函数时,发现一个问题 private ProductRegisterResponse InitResponse(int code, string message, string pw ...
- C 储存类与运算符
储存类 参考链接:https://www.runoob.com/cprogramming/c-storage-classes.html 存储类定义 C 程序中变量/函数的范围(可见性)和生命周期 au ...
- NopCommerce源代码分析之用户验证和权限管理
目录 1. 介绍 2. UML 2.1 实体类UML图 2.2 业务相关UML图 3. 核心代码分析 3.1 实体类源代码 3.2 业务相关源代码 3.3 相关控制器源代码 3.4 ...
- 【微信小程序】动态设置图片大小
我们都知道微信小程序的组件image是用来显示图片的,它有一下几个属性:1.src 图片资源地址2.mode 图片裁剪.缩放的模式3.binderror ...
- 解决使用elementUI框架el-upload跨域上传时session丢失问题
解决方法一: 1.使用elementUI框架el-upload跨域上传时,后端获取不到cookie,后端接口显示未登录,在添加了 with-credentials="true"后依 ...
- AOD.NET实现数据库事物Transaction
在开始介绍文章主要内容前先简单说一下事务 1.事务介绍 事务是一种机制.是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行.因此事务是一个不可分割的工作逻辑单元.在数据库 ...
- Try-Catch-Finally语句块执行问题
Try-Catch-Finally语句块执行问题 记录一个今天某公司的面试问题,其实我问题回答对了,但是面试官问我动手验证过没有,这还真没有,纯理论,被怼惨了,希望自己能变得更强大. Try-Catc ...
- 剑指:和为S的两个数字
题目描述 输入一个数组和一个数字 s,在数组中查找两个数,使得它们的和正好是 s. 如果有多对数字的和等于s,输出任意一对即可. 你可以认为每组输入中都至少含有一组满足条件的输出. 样例 输入:[1, ...