代码随想录 day37第八章 贪心算法 part06

●  738.单调递增的数字

●  968.监控二叉树

●  总结

1.单调递增的数字

关联 leetcode 738.单调递增的数字

  • 思路

    • 从前往后遍历
      • 可能导致数字结果变化
    • 从后往前遍历
      • 保持后面已经处理的结果,前面跟着更新
        • 不存在数字变化
  • 题解

    func monotoneIncreasingDigits(n int) int {
    	if n < 10 {
    		return n
    	}
    
    	str := strconv.Itoa(n)
    	nStr := []byte(str) //Go字符串不能修改,需要类型转换为数组
    	flag := len(nStr)   //从当前位往后全部标记为9
    
    	for i := len(nStr) - 1; i > 0; i-- {
    		//后一位小于前一位, 不满足递增
    		if nStr[i-1] > nStr[i] {
    			nStr[i-1]--
    			flag = i
    		}
    	}
    
    	for i := flag; i < len(nStr); i++ {
    		nStr[i] = '9'
    	}
    
    	res, _ := strconv.Atoi(string(nStr))
    
    	return res
    }
    

2.监控二叉树 (可以跳过)

关联 leetcode 968.监控二叉树 (可以跳过)

本题是贪心和二叉树的一个结合,比较难,一刷大家就跳过吧。

https://programmercarl.com/0968.监控二叉树.html

  • 思路
    • 从下往上看
      • 摄像头从叶子层上一层开始放置
        • 省下 叶子/2 个摄像头
        • 局部最优 —》全局最优
          • 大体思路就是从低到上,先给叶子节点父节点放个摄像头,然后隔两个节点放一个摄像头,直至到二叉树头结点
    • 二叉树遍历顺序
      • 从下往上推:后序遍历 左右中
      • 隔两个节点放一个摄像头
        • 节点可能有的状态
          • 0:节点无覆盖
          • 1:节点有摄像头
          • 2:节点有覆盖
        • 空节点的处理:
          • 补足成一个虚拟叶子,虚拟成 有覆盖的状态
      • 单层逻辑处理
        • 情况1:左右节点都有覆盖
          • 左孩子有覆盖,右孩子有覆盖,那么此时中间节点应该就是无覆盖的状态了。
        • 情况2:左右节点至少有一个无覆盖的情况
          • 如果是以下情况,则中间节点(父节点)应该放摄像头
            • left == 0 && right == 0 左右节点无覆盖
            • left == 1 && right == 0 左节点有摄像头,右节点无覆盖
            • left == 0 && right == 1 左节点有无覆盖,右节点摄像头
            • left == 0 && right == 2 左节点无覆盖,右节点覆盖
            • left == 2 && right == 0 左节点覆盖,右节点无覆盖
        • 情况3:左右节点至少有一个有摄像头
          • 如果是以下情况,其实就是 左右孩子节点有一个有摄像头了,那么其父节点就应该是2(覆盖的状态)
            • left == 1 && right == 2 左节点有摄像头,右节点有覆盖
            • left == 2 && right == 1 左节点有覆盖,右节点有摄像头
            • left == 1 && right == 1 左右节点都有摄像头
        • 情况4:头结点没有覆盖
          • 还要判断根节点,如果没有覆盖,摄像头+1
  • 题解
    • 插个眼二刷来补全

总结

  • 没有框架没有套路
  • 思路重在巧妙
    • 找不出反例就胜利了
  • 多练多见
  • 能找到局部最优
    • 累计优势 —》全局最优
      • 就是岩心
  • 多维度问题
    • 一次解决一个维度
    • 不要贪

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值