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