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,不过这个差异在容许范围之内,就不过多展开进行讨论了。

KMP算法是一种字符串匹配算法,用于在一个文本串S内查找一个模式串P的出现位置。它的时间复杂度为O(n+m),其中n为文本串的长度,m为模式串的长度。 KMP算法的核心思想是利用已知信息来避免不必要的字符比较。具体来说,它维护一个next数组,其中next[i]表示当第i个字符匹配失败时,下一次匹配应该从模式串的第next[i]个字符开始。 我们可以通过一个简单的例子来理解KMP算法的思想。假设文本串为S="ababababca",模式串为P="abababca",我们想要在S中查找P的出现位置。 首先,我们可以将P的每个前缀和后缀进行比较,得到next数组: | i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | --- | - | - | - | - | - | - | - | - | | P | a | b | a | b | a | b | c | a | | next| 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 | 接下来,我们从S的第一个字符开始匹配P。当S的第七个字符和P的第七个字符匹配失败时,我们可以利用next[6]=4,将P向右移动4个字符,使得P的第五个字符与S的第七个字符对齐。此时,我们可以发现P的前五个字符和S的前五个字符已经匹配成功了。因此,我们可以继续从S的第六个字符开始匹配P。 当S的第十个字符和P的第八个字符匹配失败时,我们可以利用next[7]=1,将P向右移动一个字符,使得P的第一个字符和S的第十个字符对齐。此时,我们可以发现P的前一个字符和S的第十个字符已经匹配成功了。因此,我们可以继续从S的第十一个字符开始匹配P。 最终,我们可以发现P出现在S的第二个位置。 下面是KMP算法的C++代码实现:
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值