力扣第 156 场双周赛

本文最后更新于 2 分钟前,文中所描述的信息可能已发生改变。

3541. 找到频率最高的元音和辅音 - 力扣(LeetCode)

解题思路

哈希表,遍历字符串即可

示例代码

python
class Solution:
    def maxFreqSum(self, s: str) -> int:
        t = 'aeiou'
        cnt = Counter(s)
        mx1 = mx2 = 0
        for k, v in cnt.items():
            if k in t:
                mx1 = max(mx1, v)
            else:
                mx2 = max(mx2, v)
        return mx1 + mx2

3542. 将所有元素变为 0 的最少操作次数 - 力扣(LeetCode)

解题思路

赛时用树状数组做的,正解用栈就可以实现

火箭毛毛虫,直接起飞

按大小遍历元素,两两遍历下标,若存在差值,说明之间操作过,之后的操作次数要分开计算

还是正解吧,只有必须操作时才更新答案

x == st[-1] 不入栈,相当于替换,等到有更小数时再操作,只用操作一次

示例代码

python
class Solution:
    def minOperations(self, nums: List[int]) -> int:
        n = len(nums)
        f = FenwickTree(n + 1)
        d = defaultdict(list)
        for i, x in enumerate(nums, 1):
            d[x].append(i)
        ans = 0
        for x in sorted(d.keys()):
            if x == 0:
                for i in d[x]:
                    f.update(i, 1)
                continue
            ans += 1
            for i, j in pairwise(d[x]):
                if f.query(j) != f.query(i):
                    ans += 1
                f.update(i, 1)
            f.update(d[x][-1], 1)
        return ans
py
class Fenwick:
    __slots__ = ["n", "c"]

    def __init__(self, n):
        self.n = n
        self.c = [0] * (n + 1)

    def update(self, x: int, delta: int):
        while x <= self.n:
            self.c[x] += delta
            x += x & -x

    def query(self, x: int) -> int:
        s = 0
        while x > 0:
            s += self.c[x]
            x -= x & -x
        return s
python
class Solution:
    def minOperations(self, nums: List[int]) -> int:
        st = []
        ans = 0
        for x in nums:
            while st and x < st[-1]:
                st.pop()
                ans += 1
            if not st or x != st[-1]:
                st.append(x)
        return ans + len(st) - (st[0] == 0)

3543. K 条边路径的最大边权和 - 力扣(LeetCode)

解题思路

记忆化搜索,赛时是从入度为 0 的节点开始的,其实是搞错了,从任一点开始都行,最多遍历 k 个节点,还可以剪枝的,自己搞复杂了

拓扑排序 DP,用刷表法转移

参考:三种方法,图中有环也能做(Python/Java/C++/Go)

注:在动态规划中,用转移来源更新当前状态叫查表法,用当前状态更新其他状态叫刷表法

示例代码

python
class Solution:
    def maxWeight(self, n: int, edges: List[List[int]], k: int, t: int) -> int:
        fmax = lambda x, y: x if x > y else y
        g = defaultdict(list)
        for x, y, w in edges:
            g[x].append((y, w))

        @cache
        def dfs(x, cnt, s):
            if cnt == k:
                nonlocal ans
                ans = fmax(ans, s)
            res = -1
            for y, w in g[x]:
                if s + w < t:
                    dfs(y, cnt + 1, s + w)

        ans = -1
        for x in range(n):
            dfs(x, 0, 0)
        dfs.cache_clear()
        return ans
python
class Solution:
    def maxWeight(self, n: int, edges: List[List[int]], k: int, t: int) -> int:
        d = [0] * n
        g = defaultdict(list)
        for x, y, w in edges:
            g[x].append((y, w))
            d[y] += 1

        ans = -1
        f = [[set() for _ in range(k + 1)] for _ in range(n)]
        q = deque(i for i, x in enumerate(d) if x == 0)

        while q:
            x = q.popleft()
            f[x][0].add(0)
            if f[x][k]:
                ans = max(ans, max(f[x][k]))
            for y, w in g[x]:
                for i in range(k):
                    for s in f[x][i]:
                        if s + w < t:
                            f[y][i + 1].add(s + w)
                d[y] -= 1
                if d[y] == 0:
                    q.append(y)
        return ans

3544. 子树反转和 - 力扣(LeetCode)

解题思路

记忆化搜索,反转或不反转,要手写记忆化搜索,memo 数组

优化,树形 DP,有点难度,以后再攻破吧

参考:树形 DP:从 O(n^2) 到 O(n)(Python/Java/C++/Go)

示例代码

python
class Solution:
    def subtreeInversionSum(self, edges: List[List[int]], nums: List[int], k: int) -> int:
        g = defaultdict(list)
        for x, y in edges:
            g[x].append(y)
            g[y].append(x)

        memo = {}

        def dfs(x: int, fa: int, d: int, r: bool) -> int:
            t = (x, d, r)
            if t in memo:
                return memo[t]

            res = nums[x] if r else -nums[x]
            for y in g[x]:
                if y == fa: continue
                res += dfs(y, x, d - 1 if d else 0, r)
            if d == 0:
                s = nums[x] if not r else -nums[x]
                for y in g[x]:
                    if y == fa: continue
                    s += dfs(y, x, k - 1, not r)
                if s > res:
                    res = s
            memo[t] = res
            return res

        ans = dfs(0, -1, 0, True)
        return ans
Classification of LeetCode Weekly Competition Questions
LeetCode Weekly Contest 449