代码随想录第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.

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

相关推荐
qmx_0731 分钟前
HTB-Jerry(tomcat war文件、msfvenom)
java·web安全·网络安全·tomcat
X同学的开始35 分钟前
数据结构之二叉树遍历
数据结构
为风而战40 分钟前
IIS+Ngnix+Tomcat 部署网站 用IIS实现反向代理
java·tomcat
limingade2 小时前
手机实时提取SIM卡打电话的信令和声音-新的篇章(一、可行的方案探讨)
物联网·算法·智能手机·数据分析·信息与通信
技术无疆3 小时前
快速开发与维护:探索 AndroidAnnotations
android·java·android studio·android-studio·androidx·代码注入
AIAdvocate4 小时前
Pandas_数据结构详解
数据结构·python·pandas
jiao000014 小时前
数据结构——队列
c语言·数据结构·算法
kaneki_lh4 小时前
数据结构 - 栈
数据结构
铁匠匠匠4 小时前
从零开始学数据结构系列之第六章《排序简介》
c语言·数据结构·经验分享·笔记·学习·开源·课程设计
C-SDN花园GGbond4 小时前
【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)
c语言·开发语言·数据结构·排序算法