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

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

相关推荐
C++忠实粉丝24 分钟前
计算机网络socket编程(5)_TCP网络编程实现echo_server
网络·c++·网络协议·tcp/ip·计算机网络·算法
kim56591 小时前
excel版数独游戏(已完成)
算法·游戏·excel·数独
cv君1 小时前
【AI最前线】DP双像素sensor相关的AI算法全集:深度估计、图像去模糊去雨去雾恢复、图像重建、自动对焦
算法
Ocean☾2 小时前
C语言-详细讲解-P1217 [USACO1.5] 回文质数 Prime Palindromes
c语言·数据结构·算法
沐泽Mu2 小时前
嵌入式学习-C嘎嘎-Day08
开发语言·c++·算法
Non importa2 小时前
汉诺塔(hanio)--C语言函数递归
c语言·开发语言·算法·学习方法
跳动的梦想家h2 小时前
黑马点评 秒杀下单出现的问题:服务器异常---java.lang.NullPointerException: null(已解决)
java·开发语言·redis
苹果醋32 小时前
前端面试之九阴真经
java·运维·spring boot·mysql·nginx
ac-er88882 小时前
PHP 二分法查找算法
开发语言·算法·php
哎呦没2 小时前
Spring Boot OA:企业办公自动化的高效路径
java·spring boot·后端