关闭

390. Elimination Game

1220人阅读 评论(2) 收藏 举报
分类:
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第二次周赛的中等难度题,看上去很简单,做法很多样,可是并不好通过。楼主的第一种做法是按照题目里的走法,一个指针按照规律在数组里往返跳来跳去,规律在于每次跳动的距离成2的指数倍增长,把握好每次跳动的距离,和每次折返的起点就行,这样做,最后可以把内存使用到常数级,时间使用为线性,可是题目的判断上线性也是无法通过的,最后的测试用例里有个一亿和十亿。当然,你如果无聊的把这俩单独算一遍,用if直接给出答案,也是可以通过的,不要问我是怎么知道的。。。

言归正传,代码还是要好好写,算法还是要认真琢磨。这种题要么就是有数学公式可以直接得到结果,要么就是有递归类型的解法。第一个不好推导,第二个还是很好想到的。
因为这里的数组结构性很强,递归的话就要找到同种类型的子问题,这是关键。虽然每次减少一半,可是剩下的数的间距总在变化,如何归类的同种子问题呢?
我们发现,第一次从左向右检索完,剩下,2 4 6 8, 其实这跟1 2 3 4的信息几乎是一样的,只是差了倍数2,所以问题就变为从右往左对规模4的问题进行操作,找到答案乘以2就行。对于从右往左,如果是1 2 3 4 5的话,检索完还剩2 4,同样是1 2的问题,如果是 1 2 3 4,剩 1 3,我们可以认为是1 2乘以2减一,总之,我们可以找到将每次的剩余子序列转化为同类子问题的方法。

需要讨论的有,每次开始的子问题是奇数还是偶数,决定下一次子问题的规模,然后这次的子问题和下次的子问题是什么递推关系。

代码如下:

class Solution {
public:
    int lastRemaining(int n) {
        return f(n);
    }
    int f (int n) { //从左往右
        if (n == 1) return 1;
        if (n == 2) return 2;
        if (n & 1 == 1) {
            return 2*g((n-1)/2);
        }
        else {
            return 2*g(n/2);
        }
    }
    int g (int n) { //从右往左
        if (n == 1) return 1;
        if (n == 2) return 1;
        if (n & 1 == 1) {
            return 2*f((n-1)/2);
        }
        else {
            return 2*f(n/2)-1;
        }
    }
};

时间复杂度O(logn),可以通过。如有更好的解法,欢迎回复讨论。

补充一个同样是O(logn)的非递归做法,每次记录删除完一遍后剩下序列的首尾两项,当然每次的删除方向和跳动距离也要不停更新,具体代码如下:

int lastRemaining(int n) {
    int base = 1, first = 1, last = n;
    bool check_first = false;
    while (first < last) { //remaining number is first, first + base, ..., last
        base *= 2;
        check_first = !check_first;
        int r = (check_first?first:last) % base;
        if (first % base == r) first += base/2;
        if (last % base == r) last -= base/2;
    }
    return first;
}

比较不好理解的就是为什么每次判断first和last除以base 的余数是否等于起始项对应的余数,判断是否保留或跳动。其实自己举几个例子就会发现,只有首尾两项的余数相等的时候才会都被删除,否则只有起始项删除。最后剩下的first和last相等,就是我们要找的值。
这里之所以这么判断,是在另一个层面观察的结果。因为从删除的那一项开始,删除的数都是跟他对于base 有同样余数的数!!!所以这就是为什么判断余数来看下次的起始项。非常巧妙。

1
0
查看评论

LeetCode—390. Elimination Game

Elimination Game思路:逐个删除的思路肯定是超时的。注意到第一次1……n从左到右删除后剩下的是2,4,6,8……这个问题等效于1……n/2(向下取证)从右往左的答案*2。那么再考虑从右往左1……2k+1,和从左往右的效果是等同的,1……2k,则剩下1,3,5,7,9,……等效于2a-1...
  • corpsepiges
  • corpsepiges
  • 2016-09-18 12:06
  • 1860

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 ...
  • imfengyitong
  • imfengyitong
  • 2017-04-12 18:17
  • 213

390. Elimination Game

leetcode周赛中等题,递归算法,折返跳动消除数组。
  • u011934885
  • u011934885
  • 2016-08-29 03:45
  • 1220

leetcode 390. Elimination Game

leetcode 390
  • feifeiiong
  • feifeiiong
  • 2017-06-22 23:47
  • 157

Leetcode 390. Elimination Game 消除游戏 解题报告

1 解题思想所谓的消除游戏,是指给出一个数字n,对应1..n的序列,然后重复如下流程: 1、选择当前序列的第1,3,5,7…..的所有奇数位置的数字消除,得到新的序列 2、选择当前序列的倒数第1,3,5,7…的所有倒数的奇数位置的数字消除,得到新的序列 3、重复12 直到只剩一个为止这道题首先...
  • MebiuW
  • MebiuW
  • 2016-09-30 22:20
  • 2953

【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 r...
  • qq_31129455
  • qq_31129455
  • 2017-01-16 05:44
  • 105

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 re...
  • algdecs
  • algdecs
  • 2016-12-12 16:54
  • 77

Leetcode 390. Elimination Game

raw blog:http://blog.csdn.net/corpsepiges/article/details/52573281  题目: There is a list of sorted integers from 1 to n. Starting from ...
  • xclfafa
  • xclfafa
  • 2017-10-10 16:56
  • 61

[leetcode]390. Elimination Game

题目链接:https://leetcode.com/problems/elimination-game/?tab=Description There is a list of sorted integers from 1 to n. Starting from left to righ...
  • xiaocong1990
  • xiaocong1990
  • 2017-03-04 10:58
  • 104

LeetCode 390. Elimination Game

Problem Statement(Source) There is a list of sorted integers from 1 to n. Starting from left to right, remove the first number and every other number ...
  • junchen1992
  • junchen1992
  • 2016-11-05 19:42
  • 175
    个人资料
    • 访问:26327次
    • 积分:1779
    • 等级:
    • 排名:千里之外
    • 原创:148篇
    • 转载:4篇
    • 译文:1篇
    • 评论:2条
    文章分类
    最新评论