【代码随想录训练营】【Day 39】【贪心-6】| Leetcode 738, 968
需强化知识点
- 968 监控二叉树,需二刷
题目
738. 单调递增的数字
- 思路:flag记录要改变数字的位置,最后flag之后的数字都变更为9
- 注意:字符串不能直接索引赋值,需要如下拼接得到新的字符串
class Solution:
def monotoneIncreasingDigits(self, n: int) -> int:
strNum = str(n)
flag = len(strNum)
for i in range(len(strNum)-1, 0, -1):
if int(strNum[i]) < int(strNum[i-1]):
flag = i
strNum = strNum[:i-1] + str(int(strNum[i-1]) - 1) + strNum[i:]
for i in range(flag, len(strNum)):
strNum = strNum[:i] + '9' + strNum[i+1:]
return int(strNum)
968. 监控二叉树
class Solution:
# Greedy Algo:
# 从下往上安装摄像头:跳过leaves这样安装数量最少,局部最优 -> 全局最优
# 先给leaves的父节点安装,然后每隔两层节点安装一个摄像头,直到Head
# 0: 该节点未覆盖
# 1: 该节点有摄像头
# 2: 该节点有覆盖
def minCameraCover(self, root: TreeNode) -> int:
# 定义递归函数
result = [0] # 用于记录摄像头的安装数量
if self.traversal(root, result) == 0:
result[0] += 1
return result[0]
def traversal(self, cur: TreeNode, result: List[int]) -> int:
if not cur:
return 2
left = self.traversal(cur.left, result)
right = self.traversal(cur.right, result)
# 情况1: 左右节点都有覆盖
if left == 2 and right == 2:
return 0
# 情况2:
# left == 0 && right == 0 左右节点无覆盖
# left == 1 && right == 0 左节点有摄像头,右节点无覆盖
# left == 0 && right == 1 左节点无覆盖,右节点有摄像头
# left == 0 && right == 2 左节点无覆盖,右节点覆盖
# left == 2 && right == 0 左节点覆盖,右节点无覆盖
if left == 0 or right == 0:
result[0] += 1
return 1
# 情况3:
# left == 1 && right == 2 左节点有摄像头,右节点有覆盖
# left == 2 && right == 1 左节点有覆盖,右节点有摄像头
# left == 1 && right == 1 左右节点都有摄像头
if left == 1 or right == 1:
return 2