代码随想录第36天 | 738.单调递增的数字 、 968.监控二叉树

一、前言:

参考文献:代码随想录

今天主要考察的是贪心,今天只有两道题目,但是都比较的难,所以我们一起来细看一下吧!

二、单调递增的数字

1、思路:

本题目的思路比较简单,就是只要找到比所给数字小,且在每一位都单调递增的数字即可;

但是实现起来却很麻烦。

首先是暴力思路:

cpp 复制代码
class Solution {
private:
    bool checkNum(int num) {
        int max = 10;
        while (num) {
            int tmp = num % 10;
            if (max >= tmp) max = tmp;
            else return false;
            num = num / 10;
        }
        return true;
    }
public:
    int monotoneIncreasingDigits(int n) {
        for (int i = n; i >= 0; i--) {
            if (checkNum(i)) return i;
        }
        return 0;
    }
};

时间复杂度为O(n * m),n,m为数字长度;

这个解法是超时的;

然后这里的贪心思路就是:

(1)将数字转化为字符串形式,然后进行从后往前的遍历;

(2)在遍历的过程中去贪心,前一个数字比后一个数字大的话就把前一个数字减1,然后后一个数字变成9;

(3)通过这种贪心算法就可实现O(n)时间复杂度的解答;

2、整体代码如下:

cpp 复制代码
class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        // 将数字转化为字符串
        string strNum = to_string(n);
        // 用于记录变成9的那一位
        int flag = strNum.size();
        for (int i = strNum.size() - 1; i  > 0; i--) { // 从后往前遍历
            if (strNum[i - 1] > strNum[i]) {
                strNum[i - 1]--;
                flag = i;
            }
        }
        for (int i = flag; i < strNum.size(); i++) {
            strNum[i] = '9';
        }
        return stoi(strNum);
    }
};

三、监控二叉树

1、思路:

这一题的思路比较复杂:

首先我们需要知道节点的状态有哪几种:

(1)覆盖,没被覆盖,有摄像头

(2)接着我们需要理清楚一共有几种情况:

1、左右子树都有覆盖的话,父节点就没覆盖了

2、左子树或者右子树有一个没有覆盖的话,父节点就必须装摄像头了

3、左右子树只要有一个有摄像头,父节点就被覆盖了

4、返回的根节点root无覆盖的话,就给根节点装摄像头;

根据这些,我们可以发现使用后序遍历,然后再根节点上做操作,就可以完成这个结果的输出;

(3)在递归中,我们首先需要确定返回值和参数:

cpp 复制代码
    int traversal(TreeNode* node)

这里的int代表的就是每个结点的状态;

(4)终止条件:

cpp 复制代码
        if (node == NULL) return 2;

为什么时返回2呢?因为当遇到空节点时,就说明他的父亲节点是叶子节点,我们需要的是,叶子节点不装摄像头,才能节省摄像头的数量(这个逻辑想必想一想就能出来),所以要返回的是被覆盖,叶子节点才不会去装摄像头;

(5)接下来就是四种情况了;

2、整体代码如下:

cpp 复制代码
class Solution {
    /*
    节点分为三种状态:
    0:无覆盖
    1:摄像头
    2:有覆盖
    分别去判断,如果遍历的是NULL就返回2,因为叶子节点不需要转摄像头
    又分为四种状态:
    1、左右子树都有覆盖的话,父节点就没覆盖了
    2、左子树或者右子树有一个没有覆盖的话,父节点就必须装摄像头了
    3、左右子树只要有一个有摄像头,父节点就被覆盖了
    4、返回的根节点root无覆盖的话,就给根节点装摄像头;

    
    */
private:
    int result;
    int traversal(TreeNode* node) {
        if (node == NULL) return 2;
        // 采用后序遍历,遍历完叶子节点,才遍历根节点
        int left = traversal(node->left);
        int right = traversal(node->right);
        // 情况1
        if (left == 2 && right == 2) {
            return 0;
        }
        // 情况2
        if (left == 0 ||right == 0) {
            // 摄像头加1
            result++;
            return 1;
        }
        // 情况3
        if (left == 1 || right == 1) {
            return 2;
        }

        return -1;
    }
public:
    int minCameraCover(TreeNode* root) {
        result = 0;
        // 情况4
        if (traversal(root) == 0) result++;
        return result;
    }
};

今日学习时间:1.5小时

leave message:

Those who don't believe in magic will never find it.

那些不相信魔法的人永远找不到它。

相关推荐
缺点内向1 天前
Java:创建、读取或更新 Excel 文档
java·excel
我搞slam1 天前
快乐数--leetcode
算法·leetcode·哈希算法
带刺的坐椅1 天前
Solon v3.4.7, v3.5.6, v3.6.1 发布(国产优秀应用开发框架)
java·spring·solon
WWZZ20251 天前
快速上手大模型:机器学习3(多元线性回归及梯度、向量化、正规方程)
人工智能·算法·机器学习·机器人·slam·具身感知
四谎真好看1 天前
Java 黑马程序员学习笔记(进阶篇18)
java·笔记·学习·学习笔记
桦说编程1 天前
深入解析CompletableFuture源码实现(2)———双源输入
java·后端·源码
东方佑1 天前
从字符串中提取重复子串的Python算法解析
windows·python·算法
java_t_t1 天前
ZIP工具类
java·zip
西阳未落1 天前
LeetCode——二分(进阶)
算法·leetcode·职场和发展
lang201509281 天前
Spring Boot优雅关闭全解析
java·spring boot·后端