Elimination Game题解
Elimination Game
这道题目出于leetcode,题目虽然很简单但是很有趣,因为有趣才能称得上游戏吧!
0x00 题目介绍
简单介绍一下题目意思
给定一个数字N(N>0),一个列表存着1~N的数字。每次从左到右从第一个数字开始,然后隔开一个数字删除数字,一直删除到最后再从右向左删除,一直删除到只剩下一个数字。
Example:
Input:
n = 9,
1 2 3 4 5 6 7 8 9
2 4 6 8
2 6
6
Output:
6
0x01 解法
解法一 按部就班
- 思想:直接按照题目意思,模拟删除步骤
- 代码:
int lastRemaining(int n) {
int start = 1, step = 1;
while (n > 1) {
//模拟删除元素一直到最后元素
start += step + (n-2)/2 * 2*step;
//每删除一轮剩余元素为该轮元素的一半
n /= 2;
//每次到达最后一个元素反向并且步数扩大两倍
//因为每次都隔开删除一个元素,
//所以下一轮的步数都是上一次的两倍
step *= -2;
}
return start;
}
算法时间复杂度:O(logN),空间复杂度O(1);
代码思想简单,易懂,一般最开始想到的也是这种算法
解法二 来去递归(一)
思想
模拟去回删除元素,去即为从左到右,回即为从右往左,用一个变量代表状态,
每轮删除后剩余这轮元素的一半.递归退出条件为当剩余元素为我们设
F(N)为从{1~N}删除的剩余元素.1). 从左往右删除
那么每次删除掉的元素为奇数项元素,剩下的元素里全部都是偶数元素,并且最终结果也在这些元素里面.
那么此时我们将所有元素同时除以2,此时元素又变为{1N/2},此时问题就变为找出{1N/2}剩余元素*2
即:F(N)=2*F(N/2);(方向----> N为偶数8) 1 2 3 4 5 6 7 8
剩余的元素在2{1,2,3,4}里面 即2F(8/2);(方向----> N为奇数9)
1 2 3 4 5 6 7 8 9
剩余元素为2{1,2,3,4}即 2F(9/2)2). 从右往左删除
如果最后一个元素是偶数,如果我们从右往左删除,剩余元素全部为奇数,为了使得剩余元素全部为偶数
(方便下一步运算,因为我们需要把N的问题分解为N/2的问题)那么我们将所有元素 加1,这样删除后
剩余元素就全部变为偶数了,为了弥补加1,我们需要在获得的结果后减1;
所以当从左往右的时候F(N) = F(N/2)-(1-N%2)=F(N/2)-1+N%2比如:当N=8 list = {1,2,3,4,5,6,7,8}
(方向<---- N为偶数8)
1 2 3 4 5 6 7 8
答案在剩余元素{1,3,5,7}里面,如果我们写作2{1,2,3,4}答案明显不对,需要修正变为2{1,2,3,4}-1即2*F(8/2)-1;(方向<---- N为奇数9)
1 2 3 4 5 6 7 8 9
剩余元素为2{1,2,3,4}即 2F(9/2)如果我们使用2*F(4/2) 答案明显不对了,所以我们需要在此基础上需要加上一个offset 1 或者在开始的基础上加一
递归版本代码
int getNext(int n,bool direction){
if(n==1) return 1;
//判断方向 从左往右
if(direction) return 2*getNext(n/2,!direction);
// 从右往左 偶数需要减一
else return 2*(getNext(n/2,!direction))-1+n%2;
}
int lastRemaining1(int n) {
return getNext(n,true);
}
时间复杂度O(logN) 空间复杂度O(logN)
- 迭代版本代码
/*
direction:删除方向 true:从左往右 false:从右往左
ratio: 记录当前删除深度
offset: 偏移值(分析如上)
*/
int lastRemaining(int n) {
bool direction = true;
int ratio = 1;
int offset = 0;
while(n!=1){
if(!direction && n%2==0)
offset+=ratio;
ratio<<=1;
n/=2;
direction=!direction;
}
return ratio-offset;
}
时间复杂度O(logN) 空间复杂度O(1)
解法三 来去递归(二)
算法思想
也是来往依次删除,把每次删除操作统一为一个方向.这样不需要每次判定方向如何,
也不需要判定是否为偶数再去减掉偏移值.如何将删除方向统一为一个方向呢?
注意:我们每次都是先从左往右删除
例如:当N=8时
方向(---->) 1 2 3 4 5 6 7 8
剩余元素在:2*{1,2,3,4}里面, 接着删除,此时我们删除方向反向为右往左.
如果我们将{1,2,3,4}反转,并用4+1-反转后的结果
即:4+1 - {1,2,3,4} = {4,3,2,1} 此时我们从右往左删除{4,3,2,1}就转化为从左往右删除{1,2,3,4}
方向就统一了起来.当然N为奇数的时候也是一样,读者可以手动模拟一下代码
int lastRemaining(int n) {
if(n <= 1) { return 1; }
//每次需要删除元素减半
n >>= 1;
//将方向反转 且结果需要乘以2
return (1 + n - lastRemaining2(n)) << 1;
};
时间复杂度O(logN) 空间复杂度O(1)
短短三行代码就解决了问题,短小精悍!
0x02结论
有趣的题目千篇一律,精致的解法百里挑一!
Elimination Game题解的更多相关文章
- Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4) 题解
Happy Birthday, Polycarp! Make Them Odd As Simple as One and Two Let's Play the Words? Two Fairs Bea ...
- Technocup 2020 Elimination Round 3题解
传送门 \(A\) 曲明连sb模拟不会做,拖出去埋了算了 //quming #include<bits/stdc++.h> #define R register #define fi fi ...
- 题解-CSA Beta Round#1 Number Elimination
Problem CSA-Beta Round#3 题意概要:给定 \(n\) 个数组成的序列,定义一次操作: 在当前序列中选择两个数,将其中较小的数从序列中删除(若两个数相同,则删除在序列中更靠前的) ...
- Codeforces Round #591 (Div. 2, based on Technocup 2020 Elimination Round 1) 题解
A..B略 C 对当前的值排序,再二分答案,然后对于(i%x==0 && i%y==0)放入大的,再放其他的贪心解决即可. #include<iostream> #incl ...
- CF1445B Elimination 题解
Content 一个比赛分两场进行,其中: 第一场的第一百名成绩为 \(a\),且第一场的前一百名在第二场中都至少得到了 \(b\) 分. 第二场的第一百名成绩为 \(c\),且第二场的前一百名在第一 ...
- hdu4975 A simple Gaussian elimination problem.(正确解法 最大流+删边判环)(Updated 2014-10-16)
这题标程是错的,网上很多题解也是错的. http://acm.hdu.edu.cn/showproblem.php?pid=4975 2014 Multi-University Training Co ...
- 高斯消元法(Gauss Elimination)【超详解&模板】
高斯消元法,是线性代数中的一个算法,可用来求解线性方程组,并可以求出矩阵的秩,以及求出可逆方阵的逆矩阵.高斯消元法的原理是:若用初等行变换将增广矩阵 化为 ,则AX = B与CX = D是同解方程组. ...
- LeetCode All in One题解汇总(持续更新中...)
突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...
- Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2)
A - Forgetting Things 题意:给 \(a,b\) 两个数字的开头数字(1~9),求使得等式 \(a=b-1\) 成立的一组 \(a,b\) ,无解输出-1. 题解:很显然只有 \( ...
随机推荐
- centos7 ambari安装HDP
环境介绍:操作系统为Centos7.1:测试设备全部为内网设备,不通公网,所以需要配置本地yum源: 首先安装ansible工具,用来批量安装ambari.java以及基础的一些配置: 一. 免密钥登 ...
- June 30th. 2018, Week 26th. Saturday
Curiosity is the wick in the candle of learning. 如果学习是一根蜡烛,那好奇心就是烛芯. From William Arthur Ward. Pleas ...
- Sql基础(零基础学数据库_SqlServer版)
刚开始学C#时候的笔记,只是些基础的语句如有错误请批评指正,谢谢,(使用SqlServer2012以上) 一. 数据库概述 SQI全称 structrued Query Language 1.数据: ...
- 彻底关闭windows10自动更新解决方案
window10的自动更新其实和window7和window8都有所不同,有些人认为只要停止了windows updates 就可以了,不会再开始了! 但是往往不是这样的,因为微软在window up ...
- 将Python 程序打包成 .exe格式入门
PyInstaller PyInstaller 是一个十分有用的第三方库,可以用来打包 python 应用程序,打包完的程序就可以在没有安装 Python 解释器的机器上运行了. 它能够在 Windo ...
- 【深度学习篇】--神经网络中的池化层和CNN架构模型
一.前述 本文讲述池化层和经典神经网络中的架构模型. 二.池化Pooling 1.目标 降采样subsample,shrink(浓缩),减少计算负荷,减少内存使用,参数数量减少(也可防止过拟合)减少输 ...
- 快速新建简单的koa2后端服务
既然前端工程化是基于NodeJS,那么选择NodeJs做前后端分离部署也是理所应当的.其实只需要实现静态资源和代理的话,用nginx才是最好的选择,用NodeJS是为了日后能进一步在服务端上实现自动构 ...
- 阿里ECS配置MSSQL远程连接的坑
mssql 2012 r2远程配置的相关文档有太多: 如:sql server2012 远程访问设置 这里不做远程配置的设置介绍.这篇随笔存在的意义在于,你除了要设置服务器,还需要到阿里云控制台设置安 ...
- java~springboot~ibatis数组in查询的实现
在ibatis的xml文件里,我们去写sql语句,对应mapper类的方法,这些sql语句与控制台上没什么两样,但在有些功能上需要注意,如where in这种从数组里查询符合条件的集合里,需要在xml ...
- springboot~mybatis里localdatetime序列化问题
问题起因 主要是使用mybatis作为ORM之后,返回的对象为Map,然后对于数据库的datetime,datestamp类型返回为时间戳而不是标准的时间,这个问题解决方案有两种,大叔分析一下: 在m ...