列表

详情


LCP 49. 环形闯关游戏

「力扣挑战赛」中有一个由 N 个关卡组成的环形闯关游戏,关卡编号为 0~N-1,编号 0 的关卡和编号 N-1 的关卡相邻。每个关卡均有积分要求,challenge[i] 表示挑战编号 i 的关卡最少需要拥有的积分。 图片.png{:width="240px"}

小扣想要挑战关卡,闯关的具体规则如下:

请帮助小扣进行计算,初始最少需要多少积分,可以挑战 环形闯关游戏 的所有关卡。

示例1:

输入:challenge = [5,4,6,2,7]

输出:4

解释: 初始选择编号 3 的关卡开启,积分为 4 挑战编号 3 的关卡,积分变为 $4 | 2 = 6$,开启 2、4 处的关卡 挑战编号 2 的关卡,积分变为 $6 | 6 = 6$,开启 1 处的关卡 挑战编号 1 的关卡,积分变为 $6 | 4 = 6$,开启 0 处的关卡 挑战编号 0 的关卡,积分变为 $6 | 5 = 7$ 挑战编号 4 的关卡,顺利完成全部的关卡

示例2:

输入:challenge = [12,7,11,3,9]

输出:8

解释: 初始选择编号 3 的关卡开启,积分为 8 挑战编号 3 的关卡,积分变为 $8 | 3 = 11$,开启 2、4 处的关卡 挑战编号 2 的关卡,积分变为 $11 | 11 = 11$,开启 1 处的关卡 挑战编号 4 的关卡,积分变为 $11 | 9 = 11$,开启 0 处的关卡 挑战编号 1 的关卡,积分变为 $11 | 7 = 15$ 挑战编号 0 的关卡,顺利完成全部的关卡

示例3:

输入:challenge = [1,1,1]

输出:1

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: long long ringGame(vector<long long>& challenge) { } };

python3 解法, 执行用时: 3500 ms, 内存消耗: 25.8 MB, 提交时间: 2023-10-10 15:50:37

class Solution:
    def ringGame(self, c: List[int]) -> int:
        n=len(c)
        hb=1
        for i in range(n):
            while not hb*2>c[i]:
                hb<<=1
        #得到最大bit
        me=max(c)
        def check(x):#判定x是否可以成功遍历数组
            if x>=me:
                return True
            vis=[0]*n
            tot=0#总共已经遍历的数
            cc=c.copy()#复制原数组,因为我们需要进行修改
            l=[(i-1)%n for i in range(n)]#等价与链表的pre指针
            r=[(i+1)%n for i in range(n)]#等价与链表的nxt指针
            def dfs(i,x):
                vis[i]=1
                cc[i]=x
                nonlocal tot
                tot+=1
                nl=l[i]#当前数pre指针
                nr=r[i]#当前数nxt指针
                while tot<n:
                    f=False
                    if cc[nl]<=x:#如果左边可以去,就删除当前数,将分数记在左边
                        x|=cc[nl]
                        if not vis[nl]:
                            tot+=1
                        vis[nl]=1
                        cc[nl]=x
                        l[nr]=nl
                        r[nl]=nr
                        nl=l[nl]
                        f=True
                        continue
                    if c[nr]<=x:#如果右边可以去,就删除当前数,将分数记在左边
                        x|=cc[nr]
                        if not vis[nr]:tot+=1
                        vis[nr]=1
                        cc[nr]=x
                        l[nr]=nl
                        r[nl]=nr
                        nr=r[nr]
                        f=True
                    if not f:
                        break
            for i,a in enumerate(cc):
                if not vis[i] and a<=x:#对i位置开始遍历
                    dfs(i,x|a)
            return tot==n
        cur=hb
        hb>>=1
        while hb:
            if not check(cur+hb-1):#判断这位1需不需要
                cur+=hb
            hb>>=1
        return cur

上一题