[代码随想录]Day32-贪心算法part06
题目:738. 单调递增的数字
思路:
从前往后找的话,如果改了一个数,那么对这个数之前的判断就不一定会成立了(eg.110)
从后往前找的话,会不断更新前面的数,后面的数因为都改成9了不需要再担心其他问题。
代码:
func monotoneIncreasingDigits(n int) int {
s := strconv.Itoa(n)
ss := []byte(s)
lens := len(ss)
if lens <= 1 {
return n
}
for i := lens-1; i > 0; i-- { // 从后向前找
if ss[i-1] > ss[i] { // 遇到不是递增
ss[i-1] -= 1 // 前面的数-1
for j := i; j < lens; j++ { // 后面数全改为9
ss[j] = '9'
}
}
}
res, _ := strconv.Atoi(string(ss))
return res
}
参考:
题目:968. 监控二叉树
思路:
所以我们要从下往上看,局部最优:让叶子节点的父节点安摄像头,所用摄像头最少,整体最优:全部摄像头数量所用最少!
在二叉树中如何从低向上推导呢?可以使用后序遍历也就是左右中的顺序,这样就可以在回溯的过程中从下到上进行推导了。
详情看参考
代码:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
var res int
func minCameraCover(root *TreeNode) int {
res = 0
if dfs(root) == 0 {
res++
}
return res
}
func dfs(root *TreeNode) int {
if root == nil {
return 2
}
left := dfs(root.Left) // 左
right := dfs(root.Right) // 右
if left == 2 && right == 2 { // 都被覆盖了不管了
return 0
}else if left == 0 || right == 0 { // 有没有被覆盖的子节点,覆盖!
res++
return 1
}else { // 否则已经覆盖了
return 2
}
}