学习内容
力扣算法
738.单调递增的数字
968.监控二叉树
具体内容
738.单调递增的数字
给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。
(当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。)
示例 1:
输入: N = 10 输出: 9
示例 2:
输入: N = 1234 输出: 1234
做题思路
从后往前遍历,例如n=332,若n[2]<n[1],则n[1]–,n[2]变成9,即求除了结果为299;若是从前向后遍历,,例如n=332,即求除了结果为329,不满足条件
解题
class Solution {
public int monotoneIncreasingDigits(int n) {
String s = String.valueOf(n);
char[] chars = s.toCharArray();
int start = s.length();
for (int i = s.length() - 2; i >= 0; i--) {
if (chars[i] > chars[i + 1]) {
chars[i]--;
start = i+1;
}
}
for (int i = start; i < s.length(); i++) {
chars[i] = '9';
}
return Integer.parseInt(String.valueOf(chars));
}
}
968.监控二叉树
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
示例 1:
输入:[0,0,null,0,0] 输出:1 解释:如图所示,一台摄像头足以监控所有节点。
做题思路
从下往上看,局部最优:让叶子节点的父节点安摄像头,所用摄像头最少,整体最优:全部摄像头数量所用最少
解题
题目分析
1、首先要从下往上遍历(左右中),因为如果从上往下,就会浪费一个根节点,二叉树的叶子节点比根节点多。
2、之后分为三种状态:2—该节点是摄像头,3—该节点是被摄像头覆盖的,1—该节点没有被摄像头覆盖
3、对null节点,只能是有覆盖,不然与题目不符合,见图片分析
4、分为四种情况如下图:
(1)左右节点被覆盖,中间节点无覆盖
(2)左右节点至少有一个无覆盖的情况,则中间节点应该放摄像头
(3)左右节点至少有一个有摄像头,中间节点节点就应该是2(覆盖的状态)
(4)遍历完后中间节点结点没有覆盖,则中间节点应该放摄像头
解题
class Solution {
int res=0;
public int minCameraCover(TreeNode root) {
// 对根节点的状态做检验,防止根节点是无覆盖状态 .
if(minCame(root)==0){
res++;
}
return res;
}
/**
节点的状态值:
0 表示无覆盖
1 表示 有摄像头
2 表示有覆盖
后序遍历,根据左右节点的情况,来判读 自己的状态
*/
public int minCame(TreeNode root){
if(root==null){
// 空节点默认为 有覆盖状态,避免在叶子节点上放摄像头
return 2;
}
int left=minCame(root.left);
int right=minCame(root.right);
// 如果左右节点都覆盖了的话, 那么本节点的状态就应该是无覆盖,没有摄像头
if(left==2&&right==2){
//(2,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;
}
}
}