LeetCode笔记:Weekly Contest 242 比赛记录

Posted 墨客无言

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode笔记:Weekly Contest 242 比赛记录相关的知识,希望对你有一定的参考价值。

0. 赛后总结

这周依然因为一些个人原因没有参加比赛,只是在赛后做了一下题目暖了暖手……

1. 题目一

给出题目一的试题链接如下:

1. 解题思路

这一题没啥好说的,分别统计一下连续的0和1的最大个数然后进行一下比较即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def checkZeroOnes(self, s: str) -> bool:
        cnt = [0, 0]
        pre = ""
        tmp = 0
        for c in s:
            if c == pre:
                tmp += 1
                continue
            if pre != "":
                cnt[int(pre)] = max(cnt[int(pre)], tmp)
            tmp = 1
            pre = c
        cnt[int(pre)] = max(cnt[int(pre)], tmp)
        return cnt[0] < cnt[1]

提交代码评测得到:耗时36ms,占用内存14.1MB。

当前最优的算法解答好事32ms,不过本质上并无不同,就不过多展开了。

2. 题目二

给出题目二的试题链接如下:

1. 解题思路

这一题我们可以采用二分法对答案进行求解。

首先,我们先排除掉两种特殊情况,一种是当给的时间过短,导致任何速度都无法准时到达的情况,另一种是给的时间过短,哪怕速度为1都能够准点到达的情况,最后,我们使用二分法即可确定最终的答案。

2. 代码实现

给出python代码实现如下:

class Solution:
    def minSpeedOnTime(self, dist: List[int], hour: float) -> int:
        n = len(dist)
        if hour <= n-1:
            return -1
        elif hour >= sum(dist):
            return 1
        l, r = 1, 10000001
        while r - l > 1:
            s = (l+r) // 2
            t = sum([math.ceil(d/s) for d in dist[:-1]]) + dist[-1]/s
            if t <= hour:
                r = s
            else:
                l = s
        return r

提交代码评测得到:耗时3136ms,占用内存28.3MB。属于当前最优的代码实现。

3. 题目三

给出题目三的试题链接如下:

1. 解题思路

这题的思路倒是挺直接的,就是动态规划,问题是怎么去设计这个动态规划解法,我们一开始按照题目进行解答,结果由于内部还需要一个for循环,导致超时。

后续参考了其他大佬们的解答之后换用思路来维护一个可见窗口,然后我们只需要考虑可移动窗口内的位置是否存在可以达到最终目的地的位置即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def canReach(self, s: str, minJump: int, maxJump: int) -> bool:
        n = len(s)
        if s[-1] == '1':
            return False
        
        dp = [0 for i in range(n)]
        dp[-1] = 1
        cnt = 0
        for i in range(n-1-minJump, -1, -1):
            cnt += dp[i+minJump]
            if i + maxJump + 1 < n:
                cnt -= dp[i + maxJump + 1]
            if s[i] == '0' and cnt > 0:
                dp[i] = 1
        print(dp)
            
        
        return dp[0] == 1

提交代码评测得到耗时400ms,占用内存15.9MB。

当前最优的解法耗时96ms,不过怎么看都不觉得他在时间复杂度上回避我们的解法更加优秀,事实上我们跑了一下它的代码之后发现还是有问题的,简直了……

4. 题目四

给出题目四的试题链接如下:

1. 解题思路

这道题的思路同样是动态规划,其核心点在于以下几点:

  1. 对于任意一次操作,选择了某一个idx之后,事实上获取的点数就是其左侧所有的所有元素的求和;
  2. 对于任意一次操作(不妨设为Alice),不会影响下一次Bob的选择操作,Bob的操作和Alice是完全一样的,只要选择令差值最大的结果即可,即是说,对于某一次操作,实际的收益就是当前位置左侧所有的元素之和减去对手下一次操作的最优收益。

综上,我们可以写出递推公式:
f ( i ) = m a x ( f ( i + 1 ) , s i − f ( i + 1 ) ) f(i) = max(f(i+1), s_i - f(i+1)) f(i)=max(f(i+1),sif(i+1))

其中, f ( i ) f(i) f(i)的定义为当当前的起始位置为第i时能够获取的最大的收益,显然,如果选取当前的元素(即取用前两个元素,包含第一个元素为补充的求和元素),那么其得到的结果就是 s i − f ( i + 1 ) s_i - f(i+1) sif(i+1),反之,如果不选取第i个元素,那么其能够获得的最大收益就会等同于 f ( i + 1 ) f(i+1) f(i+1)

综上,我们即可给出最终的算法求解。

2. 代码实现

给出python代码实现如下:

class Solution:
    def stoneGameVIII(self, stones: List[int]) -> int:
        stones = stones
        n = len(stones)
        s = list(accumulate(stones))
        
        dp = [s[i] for i in range(n)]
        for i in range(n-2, 0, -1):
            dp[i] = max(s[i] - dp[i+1], dp[i+1])
        return dp[1]

提交代码评测得到:耗时1080ms,占用内存28.5MB。

当前的最优算法耗时1000ms,不过这个差异在容许范围之内,就不过多展开进行讨论了。

以上是关于LeetCode笔记:Weekly Contest 242 比赛记录的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode笔记:Weekly Contest 317

LeetCode笔记:Weekly Contest 288

LeetCode笔记:Weekly Contest 299

LeetCode笔记:Weekly Contest 307

LeetCode笔记:Weekly Contest 325

LeetCode笔记:Weekly Contest 314