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. kao shi

    1 #include "date.h" #include "utils.h" #include <iostream> using std::cout ...

  2. 后台开发面试题(.net与java)

    最近面试了几家公司,发现大部分公司面试题有相似的地方.现在此记录下我还记得的一些题: JAVA部分: 1.Java Map 按Key排序和按Value排序: 参考链接:Java Map 按Key排序和 ...

  3. Mac系统升级至OS X Mavericks后Genymotion出现的问题及解决方法

    Apple的系统升级终于免费了,可开心满满地升级到OS X Mavericks后,Android模拟器之王Genymotion罢工了.遇到两个问题:1. Unable to load VirtualB ...

  4. DB2 体系结构 (进程模型)

    DB2 是众多关系型数据库中的一种, 关系型数据库还包括比较火的Oracle,MySQL 实例 数据库 DB2 进程模型 DB2 通过 db2start 命令启动数据库实例,即启动相应的进程和线程,并 ...

  5. DesUtils工具类

    public final class DesUtils { private static final String DES = "DES"; private static fina ...

  6. 用通俗的语言解释 Spring 中的 DI 、IOC 和AOP概念

    DI 所谓依赖,从程序的角度看,就是比如A要调用B的方法,那么A就依赖于B,反正A要用到B,则A依赖于B.所谓倒置,你必须理解如果不倒置,会怎么着,因为A必须要有B,才可以调用B,如果不倒置,意思就是 ...

  7. Oracle练习笔记

    1 基本查询 SQL> --当前用户 SQL> show user USER 为 "SCOTT" SQL> --当前用户下的表 SQL> select * ...

  8. jstl fmt标签的使用

    所有标签 fmt:requestEncoding fmt:setLocale fmt:timeZone fmt:setTimeZone fmt:bundle fmt:setBundle fmt:mes ...

  9. C 扩展库 - sqlite3 API CRUD

    CRUD struct student typedef struct STUDENT { unsigned int id; unsigned char name[16]; unsigned int a ...

  10. java几个经典的算法题目----------查询子串和等于已知数字

    给出一个排序好的数组和一个数,求数组中连续元素的和等于所给数的子数组 public class testClockwiseOutput { public static void main(String ...