day31 贪心算法05

49 阅读2分钟

56. 合并区间

文章讲解

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        result = []
        if not intervals:
            return result
        # 先排序
        intervals.sort(key=lambda x:x[0])
        result.append(intervals[0])
        # 遍历区间,和前一个比较,如果重叠了就更新前一个end;如果不重叠就加入新的区间
        for i in range(1, len(intervals)):
            if intervals[i][0] <= result[-1][1]:
                result[-1][1] = max(result[-1][1], intervals[i][1])
            else:
                result.append(intervals[i])
        return result

738. 单调递增的数字

文章讲解

思路:

思路:
1 从后往前遍历,如果前一位i-1比当前i大,那就后一位变成9,前一位-1,然后记录最早一位9
2 从第一个9开始把后面的都变成9,防止出现1000->0900的情况,变成0999
digit_list = [int(d) for d in str(num)]
class Solution:
    def monotoneIncreasingDigits(self, n: int) -> int:
        digit_list = [int(d) for d in str(n)]
        flag = len(digit_list) # 记录第一位9出现的位置

        # 从后往前遍历,两两比较大小
        for i in range(flag-1,0,-1):
            if digit_list[i-1] > digit_list[i]:
                # i变成9,i-1需要-1
                digit_list[i] = 9
                digit_list[i-1] -= 1
                flag = i # i位变成了9

        # 把第一个9之后都变成9
        for i in range(flag, len(digit_list)):
            digit_list[i] = 9
        
        return int("".join(map(str, digit_list)))

968. 监控二叉树

文章讲解

思路:


1 叶节点比上面的节点多,所以摄像头从叶节点上一层开始装,比较节省;从下往上需要使用后序遍历,左右中。
2 后续遍历树时候返回左右孩子对应的状态:
    0 无覆盖  -> 放摄像头
    1 有摄像头 -> 不用放摄像头,并且父亲也不用放
    2 有覆盖   -> 不要放摄像头,但是父亲或者爷爷要放摄像头(叶子节点)
3 base case:遇到叶子节点下的空节点时候,
4 分情况讨论中间节点:
    孩子无摄像头:
        4.1 左右孩子,有覆盖2,当前节点无覆盖0(例如叶节点)
        4.2 无覆盖2,要放摄像头了 (其中一个孩子是2无覆盖,当前一定要放摄像头 result+=1)
    孩子有存在摄像头:
        4.3 返回2,不用再加了
5 根节点:如果根节点无覆盖0,需要再加个摄像头
class Solution:
    def minCameraCover(self, root: TreeNode) -> int:
        self.result = 0  # 使用self来存储摄像头数量
        '''
        0 无覆盖,要放摄像头1,并且更新摄像头数量 (②)
        1 有摄像头,父亲为2有覆盖(③)
        2 有覆盖,父亲为0无覆盖,父亲或爷爷要放摄像头(①)
        '''
        if self.traverse(root) == 0:
            self.result += 1
        return self.result


    def traverse(self, root: TreeNode) -> int:
        # base case: 叶子下面的空节点,有覆盖2
        if not root:
            return 2
        left = self.traverse(root.left)
        right = self.traverse(root.right)

        # 后续位置
        # 1 叶子:孩子都有覆盖
        if left == 2 and right == 2:
            return 0

        # 2 孩子存在没有覆盖,需要装摄像头
        if left == 0 or right == 0:
            self.result += 1
            return 1

        # 3 孩子存在摄像头
        if left == 1 or right == 1:
            return 2