LeetCode笔记:Weekly Contest 341

本文是关于LeetCode周赛341的解题笔记,详细记录了四个题目的解题思路、Python代码实现以及部分题目的算法优化。对于每个题目,作者提供了思路分析、代码执行时间和内存使用情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 题目一

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

1. 解题思路

这一题挺直接的,就是按照题意翻译一下,对每一行都计算一下其中1元素的个数,然后找出最大的一行的位置以及其中1元素的个数进行返回即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def rowAndMaximumOnes(self, mat: List[List[int]]) -> List[int]:
        res, cnt = -1, -1
        for i, line in enumerate(mat):
            s = sum(line)
            if s > cnt:
                cnt = s
                res = i
        return (res, cnt)

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

2. 题目二

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

1. 解题思路

这一题也没想到啥好的思路,就是按照题目翻译了一下,用了一个二重循环硬解了一下。

2. 代码实现

给出python代码实现如下:

class Solution:
    def maxDivScore(self, nums: List[int], divisors: List[int]) -> int:
        divisors = sorted(divisors)
        status = [0 for _ in divisors]
        n = len(divisors)
        res, cnt = math.inf, -1
        for i, d in enumerate(divisors):
            if status[i] == 1:
                continue
            for j in range(i, n):
                if divisors[j] % d == 0:
                    status[j] = 1
            s = len([x for x in nums if x % d == 0])
            if s > cnt:
                cnt = s
                res = d
        return res

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

3. 题目三

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

1. 解题思路

这一题由于只能添加元素,因此我们只需要依序分类讨论一下即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def addMinimum(self, word: str) -> int:
        a, b = 0, 0
        res = 0
        for ch in word:
            if ch == "a":
                if a == 1 and b == 0:
                    res += 2
                elif a == 1 and b == 1:
                    res += 1
                a, b = 1, 0
            elif ch == "b":
                if a == 0 and b == 0:
                    res += 1
                elif a == 1 and b == 1:
                    res += 2
                a, b = 1, 1
            else:
                if a == 0 and b == 0:
                    res += 2
                elif a == 1 and b == 0:
                    res += 1
                a, b = 0, 0
        if a == 1 and b == 1:
            res += 1
        elif a == 1 and b == 0:
            res += 2
        return res

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

4. 题目四

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

1. 解题思路

这一题思路还是挺简单的,就是先看一下每一条路线要经过哪些点,然后就能得到所有的点被经过的次数,乘以原本的price之后我们就能获得所有点所需的成本。

然后就是一个dfs来考察不同情况下各个点如果被除二会带来的影响。

不过问题就在于时间复杂度,还是需要经过一些剪枝才能够通过测试样例,就比较无聊……

2. 代码实现

给出python代码实现如下:

class Solution:
    def minimumTotalPrice(self, n: int, edges: List[List[int]], price: List[int], trips: List[List[int]]) -> int:
        graph = defaultdict(set)
        for u, v in edges:
            graph[u].add(v)
            graph[v].add(u)
        cnt = defaultdict(int)
        
        def trip(u, v):
            nonlocal graph, cnt
            if u == v:
                cnt[u] += 1
                return [u]
            q = [(u, [u])]
            while q:
                u, path = q.pop(0)
                for w in graph[u]:
                    if len(path) >= 2 and path[-2] == w:
                        continue
                    if w == v:
                        for w in path:
                            cnt[w] += 1
                        cnt[v] += 1
                        return path + [v]
                    q.append((w, path + [w]))
            return 
        
        for u, v in trips:
            path = trip(u, v)
        
        s = [(p*cnt[u], u) for u, p in enumerate(price) if cnt[u] != 0]
        s = sorted(s, reverse=True)
        t = [x[0]//2 for x in s]
        m = len(s)
        for i in range(m-1):
            t[m-1-i-1] += t[m-1-i] 

        res = math.inf
        
        def dfs(idx, prev, banned):
            nonlocal res
            if idx >= m:
                if prev < res:
                    res = prev
                return
            if prev + t[idx] >= res:
                return
            score, u = s[idx]
            if u not in banned:
                new_banned = banned | graph[u]
                dfs(idx+1, score//2 + prev, new_banned)
            dfs(idx+1, score+prev, banned)
            return
        
        dfs(0, 0, set())
        return res             

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

3. 算法优化

看了一下当前最快的解法,耗时237ms,几乎是我们的1/4。

它的思路和我们看起来是一样的,不过实现上更加优雅,这里就简单摘录大佬的code如下,有兴趣的读者可以自行研究一下。

class Solution:
    def minimumTotalPrice(self, n: int, edges: list[list[int]], price: list[int], trips: list[list[int]]) -> int:
        g = [[] for _ in range(n)]
        for u, v in edges:
            g[u].append(v)
            g[v].append(u)

        coef = [0] * n

        for s, e in trips:
            path = []

            def dfs(v: int, p: int) -> bool:
                path.append(v)
                
                if v == e:
                    return True

                for u in g[v]:
                    if u != p:
                        if dfs(u, v):
                            return True

                path.pop()
                return False

            dfs(s, s)

            for v in path:
                coef[v] += 1

        def dfs(v: int, p: int) -> tuple[int, int]:
            wov = coef[v] * price[v]
            wv = wov // 2

            for u in g[v]:
                if u != p:
                    wu, wou = dfs(u, v)
                    wov += min(wu, wou)
                    wv += wou
            
            return wv, wov

        return min(dfs(0, 0))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值