Leetcode 周赛 203 题解

T1

https://leetcode-cn.com/problems/most-visited-sector-in-a-circular-track/
虽然直接模拟是一个办法,但是实际上兜了N圈之后最后多出来的部分就是所求
即:1→3→2→4 等效于 1→4

class Solution:
    def mostVisited(self, n: int, rounds: List[int]) -> List[int]:
        s, e = rounds[0], rounds[-1]
        if s <= e:
            # [起点, 终点]
            return list(range(s, e + 1))
        else:
            # [1, 终点]+[起点, n]
            return list(range(1, e + 1)) + list(range(s, n + 1))

T2

https://leetcode-cn.com/problems/maximum-number-of-coins-you-can-get/
贪心,排序后令A拿最多的一堆,自己拿第二多的,B拿最少的。
所以做法就是排序

class Solution:
    def maxCoins(self, piles: List[int]) -> int:
        piles.sort()
        res=0
        while piles:
            piles.pop()
            res+=piles.pop()
            piles.pop(0)
            '''
            这里应该用其他方法降低pop(0),比如计数器,但是比赛的时候还是写的快不就完事了(
            '''
        return res

T3

https://leetcode-cn.com/problems/find-latest-group-of-size-m/
这题一开始想的是二分查找,但是会遇到(没有m个)(有m个)(没有m个)的情形,所以不行
所以做法是维护区间左右端点。

class Solution:
    def findLatestStep(self, arr: List[int], m: int) -> int:
        LR = {}
        cnt = collections.defaultdict(int)
        latest = -1
        for i,c in enumerate(arr):
            L = c if c not in LR else LR[c]
            '''
            找左端点
            '''
            R = c+1 if c+1 not in LR else LR[c+1]
            '''
            找右端点
            '''
            cnt[R-L]+=1
            cnt[R-c-1]-=1
            cnt[c-L]-=1
            LR[L]=R
            LR[R]=L
            if cnt[m]>0:
                latest = i+1
        return latest

T4

https://leetcode-cn.com/problems/stone-game-v/
区间DP,状态转移方程为:

dp(i,j) 表示左右端点为i,j时,能获得的最大得分
=(i,k)区间和较小时:dp(i,k)+sum(i,k)【sum(i,k)表示i到k的区间和】
=(k,j)区间和较小时:dp(k,j)+sum(k,j)
=和相等时:max(dp(i,k),dp(k,j))+sum(k,j)
上述三者最大值,k取值为[i+1,j-1]

基本情况为:

dp(i,i+1)=dp(i,i)=0

所以很容易写出超时代码:
在这里插入图片描述
利用前缀和数组以后很容易AC:

class Solution:
    def stoneGameV(self, stoneValue: List[int]) -> int:
        sums=[0]
        for ni in stoneValue:
            sums.append(ni+sums[-1])

        @lru_cache(None)
        def helper(left,right):
            if right-1==left or left==right:
                return 0
            res=0
            l,r=sums[left],sums[right]
            for k in range(left+1,right):
                ks=sums[k]
                if ks-l<r-ks:
                    res=max(res,ks-l+helper(left,k))
                    
                elif ks-l>r-ks:
                    res=max(res,r-ks+helper(k,right))
                    
                else:
                    res=max(res,ks-l + max(helper(left,k),helper(k,right)))
            return res
        
        return helper(0,len(stoneValue))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值