LeetCode笔记:Biweekly Contest 107

本文介绍了LeetCode双周赛107中的四道题目,包括解题思路、Python代码实现及算法优化。第一题通过查找反字符串简化问题,第二题采用动态规划暴力求解,第三题和第四题同样涉及动态规划和滑动窗口策略。文章讨论了不同题目所用的策略和时间复杂度,并展示了代码实现。

1. 题目一

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

1. 解题思路

这一题由于每一个字符串都是unique的,因此事实上问题就被大幅简化了,我们只需要找到所有的反字符串同样出现过的,且其反不为自身的字符串的个数除以2即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def maximumNumberOfStringPairs(self, words: List[str]) -> int:
        s = set(words)
        res = 0
        for w in words:
            if w != w[::-1] and w[::-1] in s:
                res += 1
        return res // 2

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

2. 题目二

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

1. 解题思路

这一题感觉应该是可以直接写出答案的,不过可惜的是我没有想到很好的思路,不过考虑到题目限制了string的个数,因此我暴力地采用动态规划的方式强行枚举求出了答案……

2. 代码实现

给出python代码实现如下:

class Solution:
    def longestString(self, x: int, y: int, z: int) -> int:
        
        @lru_cache(None)
        def dfs(x, y, z, pre):
            res = 0
            if pre == "AA":
                if y > 0:
                    res = max(res, 2 + dfs(x, y-1, z, "BB"))
            elif pre == "BB" or pre == "AB":
                if x > 0:
                    res = max(res, 2 + dfs(x-1, y, z, "AA"))
                if z > 0:
                    res = max(res, 2 + dfs(x, y, z-1, "AB"))
            else:
                if x > 0:
                    res = max(res, 2 + dfs(x-1, y, z, "AA"))
                if y > 0:
                    res = max(res, 2 + dfs(x, y-1, z, "BB"))
                if z > 0:
                    res = max(res, 2 + dfs(x, y, z-1, "AB"))
            return res
        
        return dfs(x, y, z, "")

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

3. 算法优化

不过如前所述,这道题应该是有直接的解法的,想清楚了应该可以直接手写答案,事实上看其他大佬们的解答看起来就是,当前执行效率最高的代码耗时仅56ms,其算法便是如此:

class Solution:
    def longestBeautifulString(self, x: int, y: int, z: int) -> int:
        return (z + min(x, y+1) + min(x+1, y)) * 2

不过可惜的是,暂时我还没有想明白其中的解释,因此只是先在此摘录一下,后续还需要细想一下。

3. 题目三

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

1. 解题思路

这一题我的思路同样是使用动态规划,这里就不赘述了,直接给出代码如下。

2. 代码实现

给出python代码实现如下:

class Solution:
    def minimizeConcatenatedLength(self, words: List[str]) -> int:
        n = len(words)
        s = sum(len(w) for w in words)
        
        @lru_cache(None)
        def dp(idx, st, ed):
            if idx >= n:
                return 0
            
            if st == words[idx][-1]:
                s1 = 1 + dp(idx+1, words[idx][0], ed)
            else:
                s1 = dp(idx+1, words[idx][0], ed)
            
            if ed == words[idx][0]:
                s2 = 1 + dp(idx+1, st, words[idx][-1])
            else:
                s2 = dp(idx+1, st, words[idx][-1])
            
            return max(s1, s2)
        
        return s - dp(1, words[0][0], words[0][-1])

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

4. 题目四

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

1. 解题思路

这一题我最开始的思路是使用segment tree,毕竟范围内求值这个范式太接近于segment tree了,这个思路是可行的,但是不幸遇上了超时。

后来仔细一想,发现自己想复杂了,维护一个时间窗口,然后通过滑动时间窗口的方式直接对范围内有请求的server进行记录和维护即可……

难怪只是一道medium的题目,不过居然只有这么少的人提交了也是有点奇怪……

2. 代码实现

给出python代码实现如下:

class Solution:
    def countServers(self, n: int, logs: List[List[int]], x: int, queries: List[int]) -> List[int]:
        logs = sorted(logs, key=lambda x: x[1])
        m = len(logs)
        
        queries = [(idx, t) for idx, t in enumerate(queries)]
        queries = sorted(queries, key=lambda x: x[1])
        res = [0 for _ in queries]
        
        i, j = 0, 0
        cnt = {}
        for idx, t in queries:
            while j < m and logs[j][1] <= t:
                server = logs[j][0]
                if server in cnt:
                    cnt[server] += 1
                else:
                    cnt[server] = 1
                j += 1
            while i < m and logs[i][1] < t-x:
                server = logs[i][0]
                cnt[server] -= 1
                if cnt[server] == 0:
                    cnt.pop(server)
                i += 1
            res[idx] = n - len(cnt)
        return res

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值