目录
- 单调递增的数字
- 监控二叉树
LeetCode 738.单调递增的数字
LeetCode 968.监控二叉树
单调递增的数字
当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。
给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。
思路:
- 转成 str 字符串、再转成 char[] 数组,从后向前遍历,遇到 chars[i - 1] > chars[i] 的情况,chars[i - 1]–;
- 同时设置一个变量记录从第几位开始后面都是9, 再写一个 for 循环遍历设置为9.
- 最后 Integer.parseInt(String.valueOf(chars))
class Solution {public int monotoneIncreasingDigits(int n) {String str = String.valueOf(n);char[] chars = str.toCharArray();int start = chars.length; // 记录从第几位开始后面都是9 eg:100for (int i = chars.length - 1; i > 0; i--) {if (chars[i - 1] > chars[i]) {chars[i - 1]--;start = i;}}for (int i = start; i < chars.length; i++) {chars[i] = '9';}return Integer.parseInt(String.valueOf(chars));}
}
监控二叉树
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
思路: 题目示例中的摄像头都没有放在叶子节点上!
- 要从下往上看,局部最优:让叶子节点的父节点安摄像头,所用摄像头最少,整体最优:全部摄像头数量所用最少!
- 从低到上,先给叶子节点父节点放个摄像头,然后隔两个节点放一个摄像头,直至到二叉树头结点。
- 遍历顺序:后序遍历 左右中,在回溯的过程中从下到上进行推导。
- 隔两个节点放一个摄像头:每个节点可能有几种状态:
-
- 0:该节点无覆盖
-
- 1:本节点有摄像头
-
- 2:本节点有覆盖
- 空节点的状态只能是有覆盖,这样就可以在叶子节点的父节点放摄像头了
情况1:左右节点都有覆盖
左孩子有覆盖,右孩子有覆盖,那么此时中间节点应该就是无覆盖的状态了。
if (left == 2 && 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 左节点覆盖,右节点无覆盖
此时摄像头的数量要加一,并且return 1,代表中间节点放摄像头。
if (left == 0 || right == 0) {
result++;
return 1;
}
情况3:左右节点至少有一个有摄像头
如果是以下情况,其实就是 左右孩子节点有一个有摄像头了,那么其父节点就应该是2(覆盖的状态)
left == 1 && right == 2 左节点有摄像头,右节点有覆盖
left == 2 && right == 1 左节点有覆盖,右节点有摄像头
left == 1 && right == 1 左右节点都有摄像头
if (left == 1 || right == 1) return 2;
情况4:头结点没有覆盖
以上都处理完了,递归结束之后,可能头结点 还有一个无覆盖的情况。
所以递归结束之后,还要判断根节点,如果没有覆盖,result++。
/*** 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 res = 0;public int minCameraCover(TreeNode root) {// 对根节点的状态做检验,防止根节点是无覆盖状态 .if (minCame(root) == 0) res++;return res;}private int minCame(TreeNode root) {if (root == null) {return 2; // 空节点默认为 有覆盖状态,避免在叶子节点上放摄像头}int left = minCame(root.left);int right = minCame(root.right);// 如果左右节点都覆盖了的话, 那么本节点的状态就应该是无覆盖,没有摄像头if (left == 2 && right == 2) {return 0;}else if (left == 0 || right == 0) {// 左右节点都是无覆盖状态,那 根节点此时应该放一个摄像头// (0,0) (0,1) (0,2) (1,0) (2,0)// 状态值为 1 摄像头数 ++;res++;return 1;}else {// 左右节点的 状态为 (1,1) (1,2) (2,1) 也就是左右节点至少存在 1个摄像头,// 那么本节点就是处于被覆盖状态return 2;}}
}