738.单调递增的数字
思路:本题最直观的思路就是,遇到不满足条件的数,比如32,就把3减减变成2,然后后一位2直接取最大值9。关键是要确定遍历顺序,如果从前往后遍历的话,比如332,按之前的规则就会变成329,显然不对;如果从后往前遍历就会变成299,满足题目要求。
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string str=to_string(n);//转换成string类型是为了方便我们遍历
int flag=str.size();//标记从哪一位往后全都标记为9,为什么不初始化为0,比如1234,本身就是满足的,那就不会走第一个for循环里的逻辑,那走到第二个for循环时就会从开头到最后都变成9,显然是不对的
for(int i=str.size()-1;i>0;i--){
if(str[i-1]>str[i]){
str[i-1]--;
flag=i;
}
}
//遍历完一遍了,此时flag记录的是最靠前的不满足条件的位置
for(int i=flag;i<str.size();i++){
str[i]='9';
}
return stoi(str);
}
};
968.监控二叉树
思路:本题的贪心思路在于尽可能的让叶子结点的父节点安摄像头,然后从下往上处理二叉树节点,每隔两个空节点放一个摄像头,显然应该用后序遍历。每个节点可能有三种状态,
0、无覆盖 1、有摄像头 2、有覆盖 (无摄像头的情况要么就是无覆盖,要么就是有覆盖)
状态转移有四种情况,
1、左右都为有覆盖的话,其父节点就是无覆盖,等着这个父节点的父节点安一个摄像头把它覆盖
2、左右孩子只要有一个是无覆盖的情况,其父节点就必须安摄像头
3、左右孩子只要有一个安摄像头,其父节点一定是有覆盖的情况
4、如果回溯到根节点,根节点是无覆盖的情况(第一种情况返回的),根节点没有父节点了,那就还要加一个摄像头
class Solution {
public:
int result=0;
int traversal(TreeNode* node){
if(node==NULL) return 2;
int left=traversal(node->left);
int right=traversal(node->right);
//左右都有覆盖
if(left==2&&right==2) return 0;//返回无覆盖,等着父节点的父节点装摄像头将其覆盖
//左右至少有一个无覆盖
if(left==0||right==0){
result++;//一定要安摄像头
return 1;
}
//左右至少有一个摄像头
if(left==1||right==1) return 2;
return -1;
}
int minCameraCover(TreeNode* root) {
if(traversal(root)==0) result++;//如果根节点返回的是无覆盖的情况,还要安一个摄像头,因为根节点没有父节点了
return result;
}
};