56. 合并区间
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
sort(intervals.begin(),intervals.end(),[](vector<int>& a, vector<int>& b){return a[0]<b[0];});
vector<vector<int>> result;
result.push_back(intervals[0]);
for(int i=1;i<intervals.size();i++){
if(intervals[i][0]>result.back()[1])
result.push_back(intervals[i]);
else{
result.back()[1]=max(result.back()[1],intervals[i][1]);
}
}
return result;
}
};
按起点排序,依次处理,重叠区间进行合并。
738. 单调递增的数字
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string str_n=to_string(n);
int idx=str_n.length();
for(int i=str_n.length()-1; i>0; i--){
if(str_n[i]<str_n[i-1]){
str_n[i-1]--;
idx=i;
}
}
for(int i=idx; i<str_n.length(); i++){
str_n[i]='9';
}
return stoi(str_n);
}
};
贪心的思想:高位-1后,后续所有数字都可以置9,包括本来合法的数字。
968. 监控二叉树
/**
* 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:
vector<int> minCamera(TreeNode* root){
vector<int> dp(3,0);
if(root==nullptr){
dp[0]=INT_MAX/2;
dp[2]=INT_MAX/2;
return dp;
}
auto left=minCamera(root->left);
auto right=minCamera(root->right);
dp[0]=min({left[0],left[1],left[2]})+min({right[0],right[1],right[2]})+1;
dp[1]=min(left[0]+min(right[0],right[1]),right[0]+min(left[0],left[1]));
dp[2]=left[1]+right[1];
return dp;
}
int minCameraCover(TreeNode* root) {
auto res=minCamera(root);
return min(res[0],res[1]);
}
};
状态定义:
- 状态0:当前节点安装相机的时候,需要的最少相机数
- 状态1: 当前节点不安装相机,但是能被覆盖到的时候,需要的最少相机数
- 状态2:当前节点不安装相机,也不能被覆盖到的时候,需要的最少相机数
转移方程:
- dp[0]:当前节点安装,则子树可以随意发挥,即使子树的根没被覆盖,也可以被当前节点cover,所以取全部状态最小即可。
- dp[1]:当前节点不安装,还要求覆盖,只有两种可能:左子树根装了或右子树根装了,以此向上覆盖到当前节点。当一个子树装了后,另一个子树可以在状态0、1中取最小,来保证自己全覆盖,因为此时当前节点无法向下覆盖子树。
- dp[2]:取左右子树的状态1,即满足子树被覆盖到,但因为都不安装相机,所以不会向上覆盖当前节点。