目录
738.单调递增的数字
738.单调递增的数字
思路
真的,没有思路搁那无头苍蝇一样,如果能想清楚下面这个点,这道题就容易很多了。
例如:98,一旦出现strNum[i - 1] > strNum[i]的情况(非单调递增),首先想让strNum[i - 1]--,然后strNum[i]给为9,这样这个整数就是89,即小于98的最大的单调递增整数。
代码
class Solution:
def monotoneIncreasingDigits(self, N: int) -> int:
strNum = str(N)
for i in range(len(strNum) - 1, 0, -1):
# 如果当前字符比前一个字符小,说明需要修改前一个字符
if strNum[i - 1] > strNum[i]:
# 将前一个字符减1,以保证递增性质
# 使用字符串切片操作将修改后的前面部分与后面部分进行拼接
strNum = strNum[:i - 1] + str(int(strNum[i - 1]) - 1) + '9' * (len(strNum) - i)
return int(strNum)
968.监控二叉树
本题是贪心和二叉树的一个结合,比较难,一刷大家就跳过吧。
思路
我大体的想法是对的,从下往上遍历,我也预料到了题目给的每个节点的值为0是有作用的,就是写不出来,具体到怎么去隔一层放一个摄像头的代码实现就不会了。所以一定要自己亲手写出来才叫会写。(每日崩溃1/1)在代码实现时有一个很细的点,就是如果遍历到空节点后要返回2,不然叶子节点会受到影响。
代码
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
总结
可以看看贪心算法的总结,贪心本来就没啥规律,能写出个总结篇真的不容易了。
贪心完结!撒花!准备本周末的CSP考试,冲冲冲