随想录日记part29
t i m e : time: time: 2024.03.28
主要内容:今天是学习贪心算法最后一天,接下来是针对题目的讲解:1.单调递增的数字;2.监控二叉树; 3. 总结
- 738.单调递增的数字
- 968.监控二叉树
- 总结
Topic1单调递增的数字
题目:
当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。
给定一个整数 n ,返回小于或等于 n 的最大数字,且数字呈 单调递增 。
输入: n = 10 n = 10 n=10
输出: 9 9 9
思路:
思路简单直接看答案。
代码如下:
class Solution {public int monotoneIncreasingDigits(int n) {if (n >= 0 && n <= 9)return n;int count = wei(n);int[] nums = new int[count];int tem = n;for (int i = count - 1; i >= 0; i--) {nums[i] = tem % 10;tem = tem / 10;}int flag = count;for (int i = count - 1; i > 0; i--) {if (nums[i] < nums[i - 1]) {nums[i - 1]--;flag = i;}}for (int i = flag; i < count; i++) {nums[i] = 9;}int sum = 0;for (int i = 0; i < count; i++) {sum = sum * 10 + nums[i];}return sum;}private int wei(int n) {if (n < 10)return 1;int tem = n;int result = 0;while (tem != 0) {result++;tem = tem / 10;}return result;}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)
Topic2监控二叉树
题目:
给定一个二叉树,我们在树的节点上安装摄像头。节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。计算监控树的所有节点所需的最小摄像头数量。
输入: [ 0 , 0 , n u l l , 0 , 0 ] [0,0,null,0,0] [0,0,null,0,0]
输出: 1 1 1
解释: 如图所示,一台摄像头足以监控所有节点
思路:
从下往上看,局部最优:让叶子节点的父节点安摄像头,所用摄像头最少,整体最优:全部摄像头数量所用最少!局部最优推出全局最优,找不出反例,那么就按照贪心来!
大体思路就是从低到上,先给叶子节点父节点放个摄像头,然后隔两个节点放一个摄像头,直至到二叉树头结点。
此时这道题目还有两个难点:
- 二叉树的遍历
- 如何隔两个节点放一个摄像头
如何隔两个节点放一个摄像头:
每个节点可能有几种状态:有如下三种:
- 该节点无覆盖
- 本节点有摄像头
- 本节点有覆盖
分别有三个数字来表示:
0:该节点无覆盖
1:本节点有摄像头
2:本节点有覆盖
递归的终止条件: 应该是遇到了空节点,此时应该返回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】:头结点没有覆盖
以上都处理完了,递归结束之后,可能头结点 还有一个无覆盖的情况
整体代码如下:
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {int result;public int minCameraCover(TreeNode root) {result = 0;int tem = reback(root);if (tem == 0)result++;return result;}private int reback(TreeNode root) {// 递归出口if (root == null)return 2;int left = reback(root.left);int right = reback(root.right);// 【情况1】:左右节点都有覆盖if (left == 2 && right == 2) {return 0;}// 【情况2】:左右节点至少有一个无覆盖的情况if (left == 0 || right == 0) {result++;return 1;}// 【情况3】:左右节点至少有一个有摄像头if (left == 1 || right == 1) {return 2;}return -1;}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)