390. 消除游戏

题目

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/elimination-game
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。在这里插入图片描述

代码

class Solution {
    public int lastRemaining(int n) {
        int start=1;
        int step=1;//隔几个跳步
        boolean lTor =true;//判断左右遍历方向
        while (n>1){
            if (lTor){//从左往右,那么start必定变化
                start+=step;
            }else {//右往左移,若是奇数,start则变化,偶数不变
                if (n%2==1){
                    start+=step;
                }else {

                }
            }
            step*=2;//步长每次翻倍
            n/=2;//长度每次减少一半
            lTor=!lTor;//顺序每次相反
        }
        return start;
    }
}

要点

  • 本题如果模拟删除的话复杂度很高,需要观察规律找出答案
  • 仔细分析最终的胜者,发现返回的总是未删除的第一个元素,记为start
  • 我们记录start为第一个元素,当顺序删除时,start会右移
  • 逆序删除时,若此时长度为奇数,则start会右移,若是偶数,则start不变
  • 那么每次右移的长度step也需要分析,结果是没删一轮,step=step*2
  • 长度每次减少一半,若只剩一个,那就是答案,此时该元素就是start
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值