(37/60)单调递增的数字、监控二叉树

单调递增的数字

leetcode:738. 单调递增的数字

贪心法

思路

从后往前遍历,碰到不满足单调递增的,前一位数字--,标记当前位置。

从flag(包括)往后,全部赋值为9。

复杂度分析

时间复杂度:O(N)。

空间复杂度:O(N)。

N为数字位数。

注意点

  1. 数字->字符串用to_string(num)

    字符串->数字用stoi(str)

  2. 字符串赋值的时候赋值是字符'9'而不是数字9

代码实现

class Solution {
public:
// 转换成字符串方便处理
// 从后往前遍历,碰到不满足单调递增的,往前一位--,标记当前位置
// 从flag(包括)往后,全部赋值为9
// 转换回来
int monotoneIncreasingDigits(int n) {
string s = to_string(n);
int flag = s.size();
for(int i = s.size() - 1;i > 0;i--){
if(s[i - 1] > s[i]){
s[i-1]--;
flag = i;
}
}
for(int i = flag;i < s.size();i++) s[i] = '9'; // 注意,不能赋值为数字9而是字符9
return stoi(s);
}
};

监控二叉树

leetcode:968. 监控二叉树

贪心法

思路

放置的策略:

  1. 非叶子节点。要不然就浪费了上中下三层监视范围。
  2. 要全部覆盖。

采用后序遍历,根据左右子树递归后向上返回的值进行处理。

定义状态 0-无覆盖 1-摄像头 2-有覆盖

根据左右子树不同值有三种情况,对应根取值为:

  1. 0 || 0 -> 1; 优先级最高
  2. 1 || 1 -> 2;
  3. 2 && 2 -> 0;

由于是父节点取适合的值来照顾左右子节点,节点没有父节点时(root)会出现异常,所以最后再检查一下root是否被覆盖。

复杂度分析

时间复杂度:O(N)。

空间复杂度:递归栈深度。平衡时O(logN);极倾斜时O(N)。

注意点

  1. 可能左右节点一个是0、一个是2,这时候要覆盖0优先,根取1。

代码实现

后序遍历正解:

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
int result = 0;
public:
// 定义状态 0-无覆盖 1-摄像头 2-有覆盖
// 后序遍历,根据左右子树不同值有三种情况,根为:
// 1. 0 || 0 -> 1; 优先级最高
// 2. 1 || 1 -> 2;
// 3. 2 && 2 -> 0;
int postOrder(TreeNode* cur){
if(!cur) return 2; // 定义空节点状态为2,对应情况1
int left = postOrder(cur->left);
int right = postOrder(cur->right);
if(left == 0 || right == 0) {
result++;
return 1;
}else if(left == 1 || right == 1){
return 2;
}else{
return 0;
}
}
int minCameraCover(TreeNode* root) {
if(postOrder(root) == 0) return ++result;
else return result;
}
};

错版~~思路是从底向上,且从倒数第二层开始,间隔一层放置摄像头。

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
// 层序遍历,从底部往上,间隔一层放置摄像头(由下往上第二层开始放)
// 层序遍历,获得每层节点数的数组
int minCameraCover(TreeNode* root) {
if(!root) return 0;
vector<int> vec;
queue<TreeNode*> que;
que.push(root);
while(!que.empty()){
int size = que.size();
vec.push_back(size);
while(size--){
TreeNode* cur = que.front(); que.pop();
if(cur->left) que.push(cur->left);
if(cur->right) que.push(cur->right);
}
}
if(vec.size() == 1) return 1;
int sum = 0;
for(int i = vec.size() - 2;i >= 0 ;i-=2 ){
sum += vec[i];
}
return sum;
}
};
posted @   Tazdingo  阅读(691)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示