代码随想录算法训练营第37天|● 738.单调递增的数字 ● 968.监控二叉树

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

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;
    }
};

你可能感兴趣的:(算法,数据结构,leetcode)