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. 题解:很显然只有 \( ...
随机推荐
- 在Hyper-V上安装RemixOS 的Android模拟器
不想用实体机,想不想弄个快速的Android虚拟环境,今天我们就来说说把Android模拟器(RemixOS)安到Hyper-v上的办法. 1. 下载RemixOs 或者直接去 论坛获得下载地址 2 ...
- 解决@ResponseBody注解返回的json中文乱码问题
1. 简介 主要解决@ResponseBody注解返回的json中文乱码问题. 2.解决方案 2.1mvc加上注解(推荐此方法) 在mvc配置文件中假如下面配置(写在 <mvc:annotati ...
- 原生js显示消失
function showModel() {document.getElementById('container_head').style.display = 'block';}function cl ...
- Vue.js-05:第五章 - 计算属性与监听器
一.前言 在 Vue 中,我们可以很方便的将数据使用插值表达式( Mustache 语法)的方式渲染到页面元素中,但是插值表达式的设计初衷是用于简单运算,即我们不应该对差值做过多的操作.当我们需要对差 ...
- 【Android Studio安装部署系列】三十六、从Android Studio3.1.4升级到Android studio3.2【以及创建android p模拟器(未成功)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 因为想要使用Android P模拟器,所以需要将Android Studio升级到3.2版本以上. 按照官网的说法:参考<ht ...
- RecyclerFlexboxLayoutManagerDemo【使用FlexboxLayoutManager实现流式布局】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 FlexboxLayout是一个Google 开源的库项目,它将CSS Flexible Box Layout Module的类似功 ...
- 学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- JAVA 探究NIO
事情的开始 1.4版本开始,java提供了另一套IO系统,称为NIO,(New I/O的意思),NIO支持面向缓冲区的.基于通道的IO操作. 1.7版本的时候,java对NIO系统进行了极大的扩展,增 ...
- 兼容小程序的canvas画图组件jmGraph
基于CANVAS的简单画图组件让你用类似于dom的方式,在canvas上画图,感觉会不会很爽. 主页:http://graph.jm47.com/示例:http://graph.jm47.com/ex ...
- iOS weak底层实现原理
今年年底做了很多决定,离开工作三年的深圳,来到了上海,发现深圳和上海在苹果这方面还是差距有点大的,上海的市场8成使用swift编程,而深圳8成的使用OC,这点还是比较让准备来上海打拼的苹果工程师有点小 ...