链接: 738. 单调递增的数字
链接: 968. 监控二叉树
738. 单调递增的数字
- 遇到的困难
转化字符串不知道转化为字符串数组效率高还是char数组效率高,不太熟悉转化操作。
思路如下
- 时间复杂度:O(n),n 为数字长度
- 空间复杂度:O(n),需要一个字符串,转化成char数组比较方便
class Solution {
public int monotoneIncreasingDigits(int n) {
char[] str = (n + "").toCharArray();
// flag用来标记赋值9从哪里开始
// 设置为字符串长度,为了防止第二个for循环在flag没有被赋值的情况下执行
int flag = str.length;
// 从右向左遍历
for(int i = str.length-1; i > 0; i--){
// 如果当前字符比前一个字符小,说明需要修改前一个字符
if(str[i-1] > str[i]){
str[i-1]--;
flag = i;
}
}
// 将flag位置及之后的字符都修改为9,以保证最大的递增数字
for(int i = flag; i<str.length; i++){
str[i] = '9';
}
return Integer.parseInt(new String(str));
}
}
968. 监控二叉树
- 遇到的困难
1 这题主要是父节点的推测比较难,树节点的状态如何划分也是个难点
2 自己实现的时候把情况2 和情况 3 的判断顺序互换发生了错误。因为情况 3 没有把情况 2 的所有状况覆盖,具体看下面代码解释
/**
* 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;
public int minCameraCover(TreeNode root) {
res = 0;
if(traversal(root) == 0){ // root 无覆盖
res++;
}
return res;
}
public int traversal(TreeNode node){
/**
* 定义节点的三种情况
* 0 为无覆盖
* 1 为有摄像头
* 2 为有覆盖
*/
if(node == null) return 2;
int left = traversal(node.left);
int right = traversal(node.right);
// 情况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 左节点覆盖,右节点无覆盖
if(left == 0 || right == 0){
res++;
return 1;
}
// 情况3
// left == 1 && right == 2 左节点有摄像头,右节点有覆盖
// left == 2 && right == 1 左节点有覆盖,右节点有摄像头
// left == 1 && right == 1 左右节点都有摄像头
// 其他情况前段代码均已覆盖
if(left == 1 || right == 1){
return 2;
}
return -1;
}
}
总结
一句话概括贪心核心思想:局部最优推出全局最优
链接: 贪心算法总结