Leetcode brushing questions (lemonade change, catch rainwater, gems and stones, the minimum number of operations to halve an array, update the array and process the sum query, delete the maximum value in each row, parallel courses ③)

Table of contents

1. Change for lemonade

2. Receive rainwater

3. Gems and stones

4. The minimum number of operations to halve an array

5. After updating the array, process the sum query

6. Delete the maximum value in each row

7. Parallel courses③


1. Change for lemonade

class Solution:
    def lemonadeChange(self, bills: List[int]) -> bool:
        dollars = [0, 0]    # 美元数组,第一个数字记录5美元的数量,第二个数字记录10美元的数量
        for bi in bills:
            if bi == 5:
                dollars[0] += 1     # 顾客给了5美元,无需找零,5美元数量加一
            elif bi == 10:
                if dollars[0] < 1: return False     # 顾客给了10美元,但没有5美元的零钱找,无法找零
                dollars[0] -= 1     # 可以找零,5美元数量减一
                dollars[1] += 1     # 10美元数量加一
            else:
                if dollars[1] > 0 and dollars[0] > 0:
                    # 20美元优先用一张10美元和一张5美元找零
                    dollars[0] -= 1
                    dollars[1] -= 1
                elif dollars[0] >= 3:
                    # 否则用三张5美元找零
                    dollars[0] -= 3
                else:
                    # 否则无法找零
                    return False
        return True

2. Receive rainwater

class Solution:
    def trap(self, height: List[int]) -> int:
        n = len(height)
        left_max = [0] * n          # 位置i左侧(包含i)大于等于height[i]的最大值
        right_max = [0] * n         # 位置i右侧(包含i)大于等于height[i]的最大值
        left_max[0] = height[0]     # 最左侧的端点的最大值为它本身
        right_max[-1] = height[-1]  # 最右侧的端点的最大值为它本身
        for i in range(1, n):
            # 同时生成两个数组
            left_max[i] = max(left_max[i - 1], height[i])
            right_max[-(i + 1)] = max(right_max[-i], height[-(i + 1)])
        ans = 0
        for l, r, h in zip(left_max, right_max, height):
            ans += min(l, r) - h    # 位置i的雨水量取决于两侧最大值中的较小值与height[i]的差
        return ans

3. Gems and stones

class Solution:
    def numJewelsInStones(self, jewels: str, stones: str) -> int:
        count = 0
        for s in stones:
            if s in jewels:
                count += 1
        return count

4. The minimum number of operations to halve an array

class Solution:
    def halveArray(self, nums: List[int]) -> int:
        sum1 = sum(nums)          #首先利用sum函数将数组元素求和
        target = sum1 / 2         #其次算出要得到的目标值,即原数组和的一半
        queue = []                #定义一个优先权队列备用
        for num in nums:
            heapq.heappush(queue, -num)       #heapq实现的是最小堆,在本题中要实现最大堆,将元素取法异曲同工
        count = 0                #记录减少一半的次数
        while sum1 > target:
            num = heapq.heappop(queue) / 2       #heappop取出来的是堆顶,此时是负数,将其变为一半
            sum1 += num                  #因为是取的相反数,所以此处直接相加即为在原数组和上减去这个值的一半
            heapq.heappush(queue, num)        #最大元素减半以后放回队列
            count += 1
        return count
# import heapq
# queue = []
# nums = [12, 34, 1, 5]
# for num in nums:
#     heapq.heappush(queue, num)
# print(queue)
# a = heapq.heappop(queue)
# print(a)

#这是对于heapq.push和heapq.pop用法解释
#最终输出queue为[1,5,12,34], a为1

5. After updating the array, process the sum query

class Node:
    def __init__(self):
        self.l = self.r = 0
        self.s = self.lazy = 0


class SegmentTree:
    def __init__(self, nums):
        self.nums = nums
        n = len(nums)
        self.tr = [Node() for _ in range(n << 2)]
        self.build(1, 1, n)

    def build(self, u, l, r):
        self.tr[u].l, self.tr[u].r = l, r
        if l == r:
            self.tr[u].s = self.nums[l - 1]
            return
        mid = (l + r) >> 1
        self.build(u << 1, l, mid)
        self.build(u << 1 | 1, mid + 1, r)
        self.pushup(u)

    def modify(self, u, l, r):
        if self.tr[u].l >= l and self.tr[u].r <= r:
            self.tr[u].lazy ^= 1
            self.tr[u].s = self.tr[u].r - self.tr[u].l + 1 - self.tr[u].s
            return
        self.pushdown(u)
        mid = (self.tr[u].l + self.tr[u].r) >> 1
        if l <= mid:
            self.modify(u << 1, l, r)
        if r > mid:
            self.modify(u << 1 | 1, l, r)
        self.pushup(u)

    def query(self, u, l, r):
        if self.tr[u].l >= l and self.tr[u].r <= r:
            return self.tr[u].s
        self.pushdown(u)
        mid = (self.tr[u].l + self.tr[u].r) >> 1
        res = 0
        if l <= mid:
            res += self.query(u << 1, l, r)
        if r > mid:
            res += self.query(u << 1 | 1, l, r)
        return res

    def pushup(self, u):
        self.tr[u].s = self.tr[u << 1].s + self.tr[u << 1 | 1].s

    def pushdown(self, u):
        if self.tr[u].lazy:
            mid = (self.tr[u].l + self.tr[u].r) >> 1
            self.tr[u << 1].s = mid - self.tr[u].l + 1 - self.tr[u << 1].s
            self.tr[u << 1].lazy ^= 1
            self.tr[u << 1 | 1].s = self.tr[u].r - mid - self.tr[u << 1 | 1].s
            self.tr[u << 1 | 1].lazy ^= 1
            self.tr[u].lazy ^= 1


class Solution:
    def handleQuery(
        self, nums1: List[int], nums2: List[int], queries: List[List[int]]
    ) -> List[int]:
        tree = SegmentTree(nums1)
        s = sum(nums2)
        ans = []
        for op, a, b in queries:
            if op == 1:
                tree.modify(1, a + 1, b + 1)
            elif op == 2:
                s += a * tree.query(1, 1, len(nums1))
            else:
                ans.append(s)
        return ans

6. Delete the maximum value in each row

class Solution:
    def deleteGreatestValue(self, grid: List[List[int]]) -> int:
        for row in grid:
            row.sort()  # 对每一行进行排序
        score = 0       # 分数初始为0
        for j in range(len(grid[0])):
            col_max_val = grid[0][j]    # 初始化每一列最大值为该列首行的值
            for i in range(len(grid)):
                col_max_val = max(grid[i][j], col_max_val)  # 找到每一列的最大值
            score += col_max_val
        return score

7. Parallel courses③

class Solution:
    def minimumTime(self, n: int, relations: List[List[int]], time: List[int]) -> int:
        g = defaultdict(list)
        indeg = [0] * n
        for a, b in relations:
            g[a - 1].append(b - 1)
            indeg[b - 1] += 1
        q = deque()
        f = [0] * n
        ans = 0
        for i, (v, t) in enumerate(zip(indeg, time)):
            if v == 0:
                q.append(i)
                f[i] = t
                ans = max(ans, t)
        while q:
            i = q.popleft()
            for j in g[i]:
                f[j] = max(f[j], f[i] + time[j])
                ans = max(ans, f[j])
                indeg[j] -= 1
                if indeg[j] == 0:
                    q.append(j)
        return ans

Guess you like

Origin blog.csdn.net/Starinfo/article/details/131873271