[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

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)

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

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

补充题目 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

你可能感兴趣的:(算法,leetcode,算法,职场和发展)