一、前言:
参考文献:代码随想录
今天主要考察的是贪心,今天只有两道题目,但是都比较的难,所以我们一起来细看一下吧!
二、单调递增的数字
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.
那些不相信魔法的人永远找不到它。