LeetCode笔记:Biweekly Contest 91

Posted Espresso Macchiato

tags:

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

1. 题目一

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

1. 解题思路

这一题思路上还是比较直接的,排序一下之后前后对应元素的均值,然后统计一下其中distinct的元素个数即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def distinctAverages(self, nums: List[int]) -> int:
        nums = sorted(nums)
        n = len(nums)
        seen = set()
        for i in range(n//2):
            seen.add((nums[i] + nums[-i-1])/2)
        return len(seen)

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

2. 题目二

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

1. 解题思路

这一题我们的思路还是比较暴力的,首先,要统计长度为n的字符串的构造方式的话其实用一个动态规划就能够快速地求解其可能的构造方式数目。

然后,对于我们的题目,我们只需对low到high的范围内进行一个求和即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def countGoodStrings(self, low: int, high: int, zero: int, one: int) -> int:
        MOD = 10**9 + 7
        
        @lru_cache(None)
        def dp(n):
            if n == 0:
                return 1
            elif n < min(zero, one):
                return 0
            return (dp(n-zero) + dp(n-one)) % MOD
        
        res = 0
        for i in range(low, high+1):
            res = (res + dp(i)) % MOD
        return res

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

3. 题目三

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

1. 解题思路

这一题我们的思路只能说中规中矩吧,首先用一个拓扑序列的方式找到所有节点的子节点和父节点。

然后,我们求得bob的行走路径,就能求得bob到每一个点的时间。

最后,我们用一个dfs求一下alice全部可能的路径以及每一条路径上的收益即可。

需要注意的是,在第三步的dfs当中,我们需要比对alice到达每一个点时bob是否已经预先到达过这个点,然后调整一下对应点的收益即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def mostProfitablePath(self, edges: List[List[int]], bob: int, amount: List[int]) -> int:
        
        def traverse(edges):
            neighbors = defaultdict(list)
            for u, v in edges:
                neighbors[u].append(v)
                neighbors[v].append(u)
            
            upward_node = defaultdict(int)
            downward_nodes = defaultdict(list)
            s = [0]
            visited = set()
            while s != []:
                u = s.pop(0)
                visited.add(u)
                for v in neighbors[u]:
                    if v not in visited:
                        upward_node[v] = u
                        downward_nodes[u].append(v)
                        s.append(v)
            return upward_node, downward_nodes
        
        upward_node, downward_nodes = traverse(edges)
        
        bob_path = defaultdict(int)
        step = 1
        while bob != 0:
            bob_path[bob] = step
            step += 1
            bob = upward_node[bob]
        
        @lru_cache(None)
        def dfs(u, depth):
            if bob_path[u] == 0 or bob_path[u] > depth:
                score = amount[u]
            elif bob_path[u] < depth:
                score = 0
            else:
                score = amount[u] // 2
            
            if downward_nodes[u] == []:
                return score
            else:
                return score + max(dfs(v, depth+1) for v in downward_nodes[u])
            
        return dfs(0, 1)

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

4. 题目四

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

1. 解题思路

这一题我的思路还是蛮暴力的,就是找到最小的分块个数m,使得此时分完块之后每一块连同后缀的总长小于limit,此时这个情况下的分块就是我们所要的答案。

因此,问题就变成了,如何在一个给定的分块数m的情况下判断能否对字符串进行有效的切割,这个其实也简单,我们只需要求出额外的后缀所需要的长度,然后分到每一个块当中即可。

2. 代码实现

我们给出python代码实现如下:

class Solution:
    def splitMessage(self, message: str, limit: int) -> List[str]:
        n = len(message)
        
        def getlen(n):
            if n < 10:
                return n
            elif n < 100:
                return 9 + 2 * (n-9)
            elif n < 1000:
                return 9 + 2 * 90 + 3 * (n-99)
            elif n < 10000:
                return 9 + 2 * 90 + 3 * 900 + 4 * (n-999)
            elif n < 100000:
                return 9 + 2 * 90 + 3 * 900 + 4 * 9000 + 5 * (n-9999)
        
        def is_possible(m):
            tn = n + 3 * m + len(str(m)) * m + getlen(m)
            l = math.ceil(tn / m)
            return l > len(str(m))*2 + 3 and l <= limit 
        
        blocks = 0
        for i in range(1, n+1):
            if is_possible(i):
                blocks = i
                break
            
        if blocks == 0:
            return []
        
        idx = 0
        res = []
        for i in range(blocks):
            suffix = f"<i+1/blocks>"
            sub = message[idx:idx+limit - len(suffix)] + suffix
            idx += limit - len(suffix)
            res.append(sub)
        return res

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

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

LeetCode笔记:Biweekly Contest 79

LeetCode笔记:Biweekly Contest 93

LeetCode笔记:Biweekly Contest 89

LeetCode笔记:Biweekly Contest 69

LeetCode笔记:Biweekly Contest 74

LeetCode笔记:Biweekly Contest 96