第八章 贪心算法part06
738. 单调递增的数字
当且仅当每个相邻位数上的数字 x
和 y
满足 x <= y
时,我们称这个整数是单调递增的。
给定一个整数 n
,返回 小于或等于 n
的最大数字,且数字呈 单调递增 。
思路:看到题目想了一会还是没什么思路,看了题解
从后往前遍历,遇到前一位比当前位大的情况,则减1,后面位数全部设为9
class Solution {
public:
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';
}
int res=stoi(s);
return res;
}
};
968. 监控二叉树
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
没有思路,看了题解和视频,感觉题目的关键是首先理解贪心算法:从子节点开始,子节点的父节点安装摄像头,然后隔两个节点再安装下一个摄像头。
如何隔两个节点放一个摄像头
此时需要状态转移的公式,大家不要和动态的状态转移公式混到一起,本题状态转移没有择优的过程,就是单纯的状态转移!
来看看这个状态应该如何转移,先来看看每个节点可能有几种状态:
有如下三种:
- 该节点无覆盖
- 本节点有摄像头
- 本节点有覆盖
我们分别有三个数字来表示:
- 0:该节点无覆盖
- 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 {
public:
int result=0;
int traversal(TreeNode* root){
if(root==nullptr) return 2;
int left=traversal(root->left);
int right=traversal(root->right);
if(left==2&&right==2){
return 0;
}
else if(left==0||right==0){
result++;
return 1;
}
else{ //有一个子节点为1(有摄像头的情况)
return 2;
}
}
int minCameraCover(TreeNode* root) {
if(traversal(root)==0){
return result+1;
}
else return result;
}
};
贪心算法感觉没什么固定解法,还是需要对具体问题做具体分析。