LeetCode-390-消除游戏

390. 消除游戏
  • 题目

    列表 arr 由在范围 [1, n] 中的所有整数组成,并按严格递增排序。请你对 arr 应用下述算法:

    从左到右,删除第一个数字,然后每隔一个数字删除一个,直到到达列表末尾。
    重复上面的步骤,但这次是从右到左。也就是,删除最右侧的数字,然后剩下的数字每隔一个删除一个。
    不断重复这两步,从左到右和从右到左交替进行,直到只剩下一个数字。
    给你整数 n ,返回 arr 最后剩下的数字。

示例 1:

输入:n = 9
输出:6
解释:
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
arr = [2, 4, 6, 8]
arr = [2, 6]
arr = [6]

示例 2:

输入:n = 1
输出:1
  • 难度:中等

  • 分类:多看

  • 题解

    ​ 这题官方给的题解非常明白了,我在下面根据官方题解进行复述再做些补充。
    k 表 示 第 k 次 遍 历 删 除 。 k 初 始 值 为 0 , 不 难 明 白 , k 为 偶 数 从 左 到 右 删 除 , k 为 奇 数 从 右 到 左 。 a 1 k 表 示 第 k 次 删 除 的 第 一 个 数 的 值 在 官 方 题 解 当 中 考 虑 了 a n k 即 第 k 次 删 除 最 后 一 个 数 的 值 , 但 是 在 代 码 实 现 中 , 我 们 只 需 要 考 虑 第 一 个 值 的 变 化 k表示第k次遍历删除。k初始值为0,不难明白,k为偶数从左到右删除,k为奇数从右到左。\\ a_1^k表示第k次删除的第一个数的值\\ 在官方题解当中考虑了a_n^k即第k次删除最后一个数的值,但是在代码实现中,我们只需要考虑第一个值的变化\\ kkk0kka1kkankk

    • 当k为偶数时,从左到右
      • cnt为奇数,则前后两个数都要被删除,则第一个数的后移step
      • cnt为偶数,则首元素会被删除,末端元素不被删除
    • 当k为奇数时,从右到左
      • cnt为奇数,则前后两个数都要被删除
      • cnt为偶数,则首端元素被删除

    那么我们将首端元素看作指针,移动这个元素的index,一直到cnt只有1,那么这个index就是最终的数就行。

  • 代码如下:

        public int lastRemaining(int n) {
            int a1=1;
            int k=0;
            int cnt=n;
            int step=2;
            while(cnt>1){
                if(k%2==0){
                    a1=a1+step;
                }
                else{
                    a1=(cnt%2==0)?a1:a1+step;
                }
                cnt=cnt>>1;
                step=step<<1;
                k++;
            }
            return a1;
        }
    

    时间复杂度:o(logn)

    空间复杂度:o(1)

    小思考

    这里我们处理的数组是[1,n]的n为长度的连续绝对递增的数组,那么我们处理任意数组应该怎么办呢?

    那么答案也是非常简单,[1,n]的n为长度的连续绝对递增可以看作数组下标进行映射一下到[0,n-1],然后我们通过上面的代码对数组下表进行操作,最后得到的index,这个index-1对应的数,则是我们需要找到的数。其实就是简单映射关系。


来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/map-sum-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值