• [LeetCode308周赛] [前缀和] [栈] [拓扑排序]


    6160. 和有限的最长子序列

    https://leetcode.cn/problems/longest-subsequence-with-limited-sum/

    排序&前缀和&二分

    时间复杂度: O ( ( n + m ) log ⁡ n ) O((n+m)\log{n}) O((n+m)logn)

    class Solution:
        def answerQueries(self, nums: List[int], queries: List[int]) -> List[int]:
            nums.sort()
            for i in range(1, len(nums)):
                nums[i] += nums[i-1]
            # 二分查找
            for i, q in enumerate(queries):
                queries[i] = bisect_right(nums, q)
            return queries
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    6161. 从字符串中移除星号

    https://leetcode.cn/problems/removing-stars-from-a-string/

    class Solution:
        def removeStars(self, s: str) -> str:
            ans = []
            for c in s:
                if c == '*':
                    ans.pop()
                else:
                    ans.append(c)
            return ''.join(ans)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    6162. 收集垃圾的最少总时间

    https://leetcode.cn/problems/minimum-amount-of-time-to-collect-garbage/

    前缀和

    class Solution:
        def garbageCollection(self, garbage: List[str], travel: List[int]) -> int:
            gbg = []
            mi = pi = gi = 0 # 求具有该种垃圾的最远的房子的索引
            m = p = g = 0
            for i, s in enumerate(garbage):
                for c in s:
                    if c == 'M': 
                        m += 1
                        mi = i
                    elif c == 'P': 
                        p += 1
                        pi = i
                    else:  
                        g += 1
                        gi = i
                gbg.append([m, p, g])
                
            farthestDis = [mi, pi, gi]
    
            # 行驶时间求前缀和
            travel = [0] + travel
            for i in range(1, len(travel)):
                travel[i] += travel[i-1]
                
            # 每种垃圾车总时间求和
            ans = 0
            for i, dis in enumerate(farthestDis):
                ans += travel[dis] + gbg[dis][i]
                
            return ans
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    6163. 给定条件下构造矩阵

    https://leetcode.cn/problems/build-a-matrix-with-conditions/

    拓扑排序

    1. 建图,并记录每个点的入度数。
    2. 初始化队列,若某点的入度数0,直接入队。
    3. 遍历队列,每次取出队头将其加入拓扑序,然后将该点所有指向点的入度数 -1,若指向点的入度数为 0,则将该点入队。
    4. 最后得到拓扑序,若拓扑序的数目 == 点的数目,则说明无环。

    本题需要对行和列分别建图,若两个图都是有向无环图(DAG),则可以构成目标数组,每个点在拓扑序的位置就是对应列坐标以及行坐标。

    class Solution:
        def buildMatrix(self, k: int, rowConditions: List[List[int]], colConditions: List[List[int]]) -> List[List[int]]:
            # 拓扑排序
            def topo_sort(edges):
                g = [[] for _ in range(k)]       
                # 每个点的入度数目
                left = [0] * k 
                for x, y in edges:
                    # 因为点从 1 开始故, 先减去 1, 方便便利
                    x -= 1
                    y -= 1
                    g[x].append(y)
                    left[y] += 1
    
                # 拓扑序
                order = []
                
                # BFS
                # 若一个点的入度为 0, 则直接入度
                q = deque(i for i, v in enumerate(left) if v == 0) 
                while q:
                    x = q.popleft()
                    order.append(x)
                    for y in g[x]:
                        left[y] -= 1 # x 的出边指向的点的入度 - 1
                        if left[y] == 0: # 入度为 0, 入队
                            q.append(y)
                # 若有环, 拓扑序的数量不满点的个数
                return order if len(order) == k else None
    
            row = topo_sort(rowConditions)
            if row == None:
                return []
            col = topo_sort(colConditions)
            if col == None:
                return []
            
            # 形成映射, 方便查找列坐标
            col = {x : i for i, x in enumerate(col)}
            # 初始化答案数组
            ans = [[0] * k for _ in range(k)]
            for i, x in enumerate(row):
                ans[i][col[x]] = x + 1 # 之前减1, 现在加上去
            return ans
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    补充题目 LeetCode 207. 课程表

    https://leetcode.cn/problems/course-schedule/
    思路一样,代码微调即可。

    class Solution:
        def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
            g = [[] for _ in range(numCourses)]
    
            left = [0] * numCourses
    
            for x, y in prerequisites:
                g[x].append(y)
                left[y] += 1
            
            q = deque(i for i, v in enumerate(left) if v == 0)
            order = []
            while q:
                x = q.popleft()
                order.append(x)
                for y in g[x]:
                    left[y] -= 1
                    if left[y] == 0:
                        q.append(y)
                        
            return True if len(order) == numCourses else False
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    i++与++i的运算和效率区别
    Shell:一键部署pxe
    学编程始于C语言,但只学C远远不够的!
    (246)Verilog HDL:四选一多路器
    二:OpenCV图片叠加逻辑运算
    网页vue3导出pdf
    spring boot自动装配及自动装配条件判断
    语义分割笔记(二):DeepLab V3对图像进行分割(自定义数据集从零到一进行训练、验证和测试)
    解决react报错“JSX 表达式必须具有一个父元素“
    文件夹高效改名,批量设置文件夹仅显示编号无名称的方法“
  • 原文地址:https://blog.csdn.net/qq_39906884/article/details/126569472