代码随想录Day37 | 738.单调递增的数字 968.监控二叉树
- 738.单调递增的数字
- 968.监控二叉树
738.单调递增的数字
文档讲解:代码随想录
视频讲解: 贪心算法,思路不难想,但代码不好写!LeetCode:738.单调自增的数字
状态
本题可以通过比较低位与高位,如果低位比高位小,则变为9,同时比较高位的高位,如果高位比高位的高位大,那么就–。遍历完一次后,再从高位向低位遍历,如果高位比低位大,那么修改低位的值为高位的值
//统计每个位的字符
//然后按个位 十位这样组成一个数组
//如果i<i+1那么将nums[i]变为9
//接着比较i+1>=i+2 或者 i+1是否是最后一个 nums[i+1] -1
//最后在从右向左遍历,如果后遍历比前遍历的小则修改
class Solution {
public:int monotoneIncreasingDigits(int n) {if(n ==0) return 0;vector<int> check;while(n){int temp = n%10;check.push_back(temp);n = n/10;}for(int i = 0;i<check.size()-1;i++){if(check[i]<check[i+1]){check[i]=9;if(i+1 == check.size()-1 || (i+2<check.size() && check[i+1]>=check[i+2])){check[i+1]--;}}}int res = 0;for(int i = check.size()-1;i>0;i--){if(check[i-1]< check[i]){check[i-1] = check[i];}res *= 10;res += check[i];}res *= 10;res += check[0];return res;}
};
代码随想录中给出了另外一种方法,那就是如果遇到低位比高位大的情况,先将低位–,然后记录此时高位的位置。待一次遍历结束后,从记录的位置向高位赋值9。
//统计每个位的字符
//然后按个位 十位这样组成一个数组
//如果i<i+1那么将nums[i]变为9
//接着比较i+1>=i+2 或者 i+1是否是最后一个 nums[i+1] -1
//最后在从右向左遍历,如果后遍历比前遍历的小则修改
class Solution {
public:int monotoneIncreasingDigits(int n) {if(n ==0) return 0;vector<int> check;while(n){int temp = n%10;check.push_back(temp);n = n/10;}//记录当前的第一个需要更改的位置int flag = -1;for(int i = 0;i<check.size()-1;i++){if(check[i+1] > check[i]){flag = i;check[i+1]--;}}for(int i = flag;i>=0;i--){check[i] = 9;}int res = 0;for(int i = check.size()-1;i>=0;i--){res *= 10;res += check[i];}return res;}
};
968.监控二叉树
文档讲解:代码随想录
视频讲解: 贪心算法,二叉树与贪心的结合,有点难… LeetCode:968.监督二叉树
状态
本题首先需要考虑的是摄像头该如何放置,为了使得摄像头最少,那么在叶子节点上就不应该放置摄像头,而应当在叶子节点的父节点上放置。
接着就是采用后序遍历,应为我们要根据子结点的放置来判断中间节点的放置情况。
对于一个节点来说总共可能出现3种情况
没有被覆盖 – 0
作为摄像头节点 – 1
作为被覆盖节点 – 2
现在来考虑返回值,当我们遇见空节点时,空节点只能作为被覆盖节点即返回2,因为首先空节点不能作为摄像头节点,其次如果其没有被覆盖,那么叶子节点一定有摄像头
if(root == nullptr) return 2;
最后就是单层逻辑的处理
- 如果左右节点都是被覆盖节点 返回值为2
那么此时的中间节点应当为0, - 如果左右节点至少有一个无覆盖的情况 返回值为0
那么中间节点应当放置一个摄像头 应当为1
- 左右节点至少有一个摄像头, 即有一个返回值为1
那么 中间节点应当为2
- 对根节点需要单独判断
如果根节点没有被覆盖,那么就需要再增加一个摄像头。
/*** 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 res = 0;
public:int SetCamera(TreeNode* root){//空节点if(root == nullptr) return 2;int left = SetCamera(root->left);int right = SetCamera(root->right);//如果左右节点都是 2if(left == 2 && right ==2){return 0;}//如果左右节点有一个是没有被覆盖if(left == 0|| right == 0){res++;return 1;}//如果左右节点有一个是摄像头,返回1if(left == 1 || right == 1){return 2;}return -1;}
public:int minCameraCover(TreeNode* root) {if(SetCamera(root) == 0){res++;}return res;}
};