(37/60)单调递增的数字、监控二叉树

单调递增的数字

leetcode:738. 单调递增的数字

贪心法

思路

从后往前遍历,碰到不满足单调递增的,前一位数字--,标记当前位置。

从flag(包括)往后,全部赋值为9。

复杂度分析

时间复杂度:O(N)。

空间复杂度:O(N)。

N为数字位数。

注意点

  1. 数字->字符串用to_string(num)

    字符串->数字用stoi(str)

  2. 字符串赋值的时候赋值是字符'9'而不是数字9

代码实现

class Solution {
public:
    // 转换成字符串方便处理
    // 从后往前遍历,碰到不满足单调递增的,往前一位--,标记当前位置
    // 从flag(包括)往后,全部赋值为9
    // 转换回来
    int monotoneIncreasingDigits(int n) {
        string s = to_string(n);
        int flag = s.size();
        for(int i = s.size() - 1;i > 0;i--){
            if(s[i - 1] > s[i]){
                s[i-1]--;
                flag = i;
            }
        }
        for(int i = flag;i < s.size();i++) s[i] = '9';	// 注意,不能赋值为数字9而是字符9

        return stoi(s);
    }
};

监控二叉树

leetcode:968. 监控二叉树

贪心法

思路

放置的策略:

  1. 非叶子节点。要不然就浪费了上中下三层监视范围。
  2. 要全部覆盖。

采用后序遍历,根据左右子树递归后向上返回的值进行处理。

定义状态 0-无覆盖 1-摄像头 2-有覆盖

根据左右子树不同值有三种情况,对应根取值为:

  1. 0 || 0 -> 1; 优先级最高
  2. 1 || 1 -> 2;
  3. 2 && 2 -> 0;

由于是父节点取适合的值来照顾左右子节点,节点没有父节点时(root)会出现异常,所以最后再检查一下root是否被覆盖。

复杂度分析

时间复杂度:O(N)。

空间复杂度:递归栈深度。平衡时O(logN);极倾斜时O(N)。

注意点

  1. 可能左右节点一个是0、一个是2,这时候要覆盖0优先,根取1。

代码实现

后序遍历正解:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
private:
    int result = 0;
public:
    // 定义状态 0-无覆盖 1-摄像头 2-有覆盖
    // 后序遍历,根据左右子树不同值有三种情况,根为:
    // 1. 0 || 0 -> 1;   优先级最高
    // 2. 1 || 1 -> 2;
    // 3. 2 && 2 -> 0;
    int postOrder(TreeNode* cur){
        if(!cur) return 2; // 定义空节点状态为2,对应情况1
        int left = postOrder(cur->left);
        int right = postOrder(cur->right);
        
        if(left == 0 || right == 0) {
            result++;
            return 1;
        }else if(left == 1 || right == 1){
            return 2;
        }else{
            return 0;
        }
    }

    int minCameraCover(TreeNode* root) {
        if(postOrder(root) == 0) return ++result;
        else return result;
    }
};

错版~~思路是从底向上,且从倒数第二层开始,间隔一层放置摄像头。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    // 层序遍历,从底部往上,间隔一层放置摄像头(由下往上第二层开始放)
    // 层序遍历,获得每层节点数的数组
    int minCameraCover(TreeNode* root) {
        if(!root) return 0;
        vector<int> vec;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()){
            int size = que.size();
            vec.push_back(size);
            while(size--){
                TreeNode* cur = que.front(); que.pop();
                if(cur->left) que.push(cur->left);
                if(cur->right) que.push(cur->right);
            }
        }
        if(vec.size() == 1) return 1;
        int sum = 0;
        for(int i = vec.size() - 2;i >= 0 ;i-=2 ){
            sum += vec[i];
        }

        return sum;
    }
};
posted @ 2024-03-05 21:18  Tazdingo  阅读(707)  评论(0)    收藏  举报