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
算法分析

首先可以想到的最原始的一个方法就是构造一个列表,一遍一遍地来回删除其中的元素,直到列表里只剩下一个元素。

但这显然不是问题的设计的初衷。

首先设输入数据为 n 时,最终结果为 f(n).很显然,有 f(1)=1,f(2)=2.

当 n=2k 时,从1,3,5,... ,2k-1 删除奇数项后,剩余的是2,4,6,... ,2k, 共 k 个偶数项。

当 n=2k+1 时,从1,3,5,... ,2k-1 ,2k+1 删除奇数项后,剩余的是2,4,6,... ,2k, 共 k 个偶数项。

这两种情况在从左到右删除一遍后,剩下的内容相同,所以最终剩下的一项也相同,所以我们可以得出结论:

f(2k+1)=f(2k)

所以,我们只需考虑 n 为偶数的情况。

假设 n=n1=k (k=1,2,3,...)时,f(n1)=m1,那么当n=n2=2*n1=2k (k=1,2,3,...)时,从左到右第一遍删除奇数后,还剩下 k 个偶数,此时从右往左删除,情况跟n=n1时从左往右开始删除类似,则最终剩下的是从 2k 往左数第 m1 个偶数,所以f(n2)=n2-2*(m1-1),即:

f(2k)=2k-2*f(k)+2

同理,有

f(2(k+1))=2(K+1)-2*f(2^k)+2

对上式两边同时除以 2^(k+1),有:

f(2(K+1))/2(k+1)= - f(2k)/2k +1/2^k + 1.

记 g(k)=f(2k)/2k,则:

g(k+1)= -g(k)+1/2^k+1.

由于上式两边函数项正负号不同,难以推出通项公式,所以我们需要进一步推理,有:

g(k+1)

= -g(k)+1/2^k+1

= -[-g(k-1)+1/2^(k-1)+1] + 1/2^k +1

= g(k-1)-1/2^k

且有 g(0)=f(1)/1=1, g(1)=f(2)/2=1.

则:

(i) 当 k=2m (m=1,2,3,...) 时,有:

g(2m)

=g(2m-2)-1/2^(2m-1)

=g(2m-4)-1/2(2m-3)-1/2(2m-1)

=g(2m-6)-1/2(2m-5)-1/2(2m-3)-1/2^(2m-1)

=...

=g(0)-1/21-1/23-1/25-...-1/2(2m-1)

=1-(2-2/4^m)/3

=(2/4^m+1)/3

当取m=0时,g(2m)=1=g(0),所以,当 k=2m (m=0,1,2,3,...)时,g(2m)=(2/4^m+1)/3

(ii) 当 k=2m+1 (m=1,2,3,...) 时,有:

g(2m+1)

=g(2m-1)-1/2^(2m)

=g(2m-3)-1/2(2m-2)-1/2(2m)

=...

=g(1)-1/22-1/24-1/26-...-1/2(2m)

=1-(1-1/4^m)/3

=(1/4^m+2)/3

当取m=0时,g(2m+1)=1=g(1),所以,当 k=2m+1 (m=0,1,2,3,...)时,g(2m+1)=(1/4^m+2)/3

又因为 f(2k)=2k*g(k),所以,对于给定的 n ,当 n 为2^k时,我们可以根据k是奇数还是偶数得出f(n)的公式。即:

(i) 当 n=2^(2m) (m=0,1,2,3,...)时,有:

f(n)

=f(2^(2m))

=2^(2m)*g(2m)

=n*(2/4^m+1)/3

=(n+2)/3

(ii) 当 n=2^(2m+1) (m=0,1,2,3,...)时,有:

f(n)

=2^(2m+1)*g(2m+1)

=n*(1/4^m+2)/3

=(2n+2)/3

所以,对于输入的 n ,如果是 1,我们直接返回1 。否则,判断其是否为偶数,如果不是,则将其做减1处理,因为 f(2k+1)=f(2k).此时保证n为偶数。

然后判断 n 是否为 2^k,如果是,则根据上面推理出的公式进行计算;如果不是,则递归计算 f(n/2) ,因为 f(n)=n-2f(n/2)+2.

代码如下:

Java算法实现

public class Solution {
public int lastRemaining(int n) {
if(n==1)
return 1;
if(n==2)
return 2;
if((n&0x1)==0x1){
n--;//化为偶数,因为 f(2k+1)=f(2k)
}
if(((n-1)&n)==0){
//为2的整数幂
int index=0;
int tmpN=n;
tmpN=tmpN>>>1;
while(tmpN>0){
//n=2^k,此处用 index 表示k的值
index++;
tmpN=tmpN>>>1;
}
int ans=0;
if((index&1)==1){
//index为奇数
//对应f(n)=(2n+2)/3,此处 tmpN=2n
tmpN=n<<1;
}
else{
//index为偶数
//对应f(n)=(n+2)/3,此处 tmpN=n
tmpN=n;
}
ans=(tmpN+2)/3; //tmpN=n 或 tmpN=2n
return ans; }
else{
//n不是2的整数幂,但目前已经能保证n为偶数,递归计算
int tmpAns=lastRemaining(n>>>1);
int ans=n-2*tmpAns+2;
return ans;
}
}
}

LeetCode赛题390----Elimination Game的更多相关文章

  1. LeetCode赛题515----Find Largest Element in Each Row

    问题描述 You need to find the largest element in each row of a Binary Tree. Example: Input: 1 / \ 2 3 / ...

  2. LeetCode赛题----Find Left Most Element

    问题描述 Given a binary tree, find the left most element in the last row of the tree. Example 1: Input: ...

  3. LeetCode赛题395----Longest Substring with At Least K Repeating Characters

    395. Longest Substring with At least K Repeating Characters Find the length of the longest substring ...

  4. LeetCode赛题394----Decode String

    394. Decode String Given an encoded string, return it's decoded string. The encoding rule is: k[enco ...

  5. LeetCode赛题393----UTF-8 Validation

    393. UTF-8 Validation A character in UTF8 can be from 1 to 4 bytes long, subjected to the following ...

  6. LeetCode赛题392---- Is Subsequence

    392. Is Subsequence Given a string s and a string t, check if s is subsequence of t. You may assume ...

  7. LeetCode赛题391----Perfect Rectangle

    #391. Perfect Rectangle Given N axis-aligned rectangles where N > 0, determine if they all togeth ...

  8. 【LeetCode】390. Elimination Game 解题报告(Python)

    [LeetCode]390. Elimination Game 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/elimina ...

  9. 这样leetcode简单题都更完了

    这样leetcode简单题都更完了,作为水题王的我开始要更新leetcode中等题和难题了,有些挖了很久的坑也将在在这个阶段一一揭晓,接下来的算法性更强,我就要开始分专题更新题目,而不是再以我的A题顺 ...

随机推荐

  1. 编程开发之--java多线程学习总结(3)类锁

    2.使用方法同步 package com.lfy.ThreadsSynchronize; /** * 1.使用同步方法 * 语法:即用 synchronized 关键字修饰方法(注意是在1个对象中用锁 ...

  2. Cause: org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierIm Lorg/gradle/api/artifacts/ModuleIdentifier;

    今天碰到一个问题, 正常的下载gradle到本地,然后到spring官网上通过他们提供的start.spring.io创建一个demo项目, 然后在idea中打开,并配置下载的gradle到idea中 ...

  3. k-近邻算法 python实现

    必要的注释已经写在code里面了: import operator from numpy import* def init(): grp=array([[1.0,1.1],[1.0,1.0],[0,0 ...

  4. mfix中统计气泡体积

    先转换为point data 提取空隙率在0.45-1.0之间的网格,为后面提取气泡内网格做准备 把free board部分去掉 然后积分 选择cell data后就得到气泡内所有网格的体积和,如果网 ...

  5. 防止过拟合:L1/L2正则化

    正则化方法:防止过拟合,提高泛化能力 在训练数据不够多时,或者overtraining时,常常会导致overfitting(过拟合).其直观的表现如下图所示,随着训练过程的进行,模型复杂度增加,在tr ...

  6. springcloud(十)-Zuul微服务网关

    为什么要使用微服务网关 前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服 ...

  7. Chrome获取微信授权,调试公众号页面

    1.目的 你可能遇到过这种情况,在微信中打开公众号是这样的. 复制链接,在chrome中打开是这样的. 博主今天要解决的就是,如果在chrome中加载需要微信授权的页面,至于加载成功后要干嘛,测试?抓 ...

  8. docker pull 私有镜像

    错误演示 [root@CentOS7 jdk8]# curl http://10.20.2.29:5000/v2/_catalog {"repositories":["d ...

  9. vue引入bootstrap和fontawesome

    npm install jquery npm install bootstrap npm install popper.js. import $ from 'jquery' import 'boots ...

  10. Executors多线程

    介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...