Day37 贪心算法 LeetCode 738 968

97 阅读1分钟

738. 单调递增的数字

心得

  • 暴力超时

题解

  • 模拟小于的替换结果,即减少到最小的9结尾的数值,以此迭代,左右遍历顺序尝试下即可,注意需要标志位确保类似xx99结尾
class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        string strNum = to_string(n);
// 初值确保原来就符合条件的情况不会执行循环,同时保证1000 处理后999而不是900
        int flag = strNum.size(); 

        for (int i = strNum.size() - 1; i > 0; i--) {
            if (strNum[i - 1] > strNum[i]) {
                flag = i;
                strNum[i - 1]--;
            }
        }
        for (int i = flag; i < strNum.size(); i++) {
            strNum[i] = '9';
        }
        return stoi(strNum);
    }
};

968. 监控二叉树

心得

  • 大概想的是后序遍历,优先靠近叶子结点的位置先放摄像头,但是细节还是很多

题解

  • 后序遍历,通过左右孩子的状态来判断结点是否需要放置摄像头,自定义三种状态,同时空结点状态也要考虑,便于逻辑统一,根结点需要单独考虑
class Solution {
private:
    int result;
    int traversal(TreeNode* cur) {
        // 定义结点三种状态,0——无覆盖,1——摄像头,2——有覆盖
        if (cur == nullptr) return 2;
        int left = traversal(cur->left);
        int right = traversal(cur->right);
        // 情况1 左右都有覆盖,则当前啥也不用干,针对叶子结点情况
        if (left == 2 && right == 2) {
            return 0;
        }
        // 情况2 左右都无覆盖,放置摄像头
        if (left == 0 || right == 0) {
            result++;
            return 1;
        }
        // 情况3 左右 有摄像头,则当前必被覆盖
        if (left == 1 || right == 1) {
            return 2;
        }
        return -1;
    }
public:
    int minCameraCover(TreeNode* root) {
        result = 0;
        if (traversal(root) == 0) { // 根结点覆盖情况
            result++;
        }
        return result;
    }
};