合并区间 leetcode 56
先把第一个区间放入结果集,查找重叠区间,如果和结果集中最后一个区间重合则将结果集最后一个区间的右边界取当前遍历区间右边界与结果集最后一个区间右边界的最大值以合并区间,如果不重叠则将当前区间放入结果集。
class Solution {
public:
static bool cmp(const vector<int>& a,const vector<int>& b){
if(a[0]==b[0]) return a[1]<b[1];
return a[0]<b[0];
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
sort(intervals.begin(),intervals.end(),cmp);
vector<vector<int>> res;
res.push_back(intervals[0]);
for(int i=1;i<intervals.size();i++){
if(intervals[i][0]<=res.back()[1]){
res.back()[1]=max(intervals[i][1],res.back()[1]);
}else res.push_back(intervals[i]);
}
return res;
}
};
单调递增的数字 leetcode 738
先把数字转化为字符串便于处理,flag用来记录从flag索引开始之后以及其本身全部置为9,从后向前遍历,如果当前数字小于前一位,那么前一位数字--,并记录当前索引为flag。
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string str=to_string(n);
int flag=str.size();
for(int i=str.size()-1;i>0;i--){
if(str[i-1]>str[i]){
str[i-1]--;
flag=i;
}
}
for(int i=flag;i<str.size();i++){
str[i]='9';
}
return stoi(str);
}
};
总结
学到了to_string函数和stoi函数。
监控二叉树 leetcode 968
贪心思路:尽量在子节点的父节点放摄像头,然后向上每隔两个节点放置摄像头,所以使用后序遍历二叉树(左右中)。
如何控制每隔两个节点放置摄像头呢,需要记录每个节点的状态,然后根据左右孩子节点的状态去确定父节点的状态。
节点状态:无覆盖(0)、有摄像头(1)、有覆盖(2)。空节点设置为有覆盖状态。
后序遍历情况:
(1)当前遍历节点左右孩子都为有覆盖状态,则当前遍历节点的父节点就是无覆盖状态。
(2)当前遍历节点左右孩子最少有一个是无覆盖状态,则当前遍历节点的父节点就是有摄像头状态。
(3)当前遍历节点左右孩子是有摄像头状态,则当前遍历节点的父节点就是有覆盖状态。
(4)如果遍历完成之后根节点是无覆盖状态,则在根节点加一个摄像头。
注:2和3顺序不能反,左右其中至少有一个为1的这种情况包含了一种特殊情况:左0右1或者左1右0,这种情况即符合情况2也符合情况3,但是这种情况的正确处理操作是父节点加一个摄像头,所以得让第2种情况在前面,先判断这个特殊情况。(来自b站视频一位大佬评论)
class Solution {
public:
int res=0;
int traversal(TreeNode* cur){
if(cur==nullptr) return 2;
int left=traversal(cur->left);
int right=traversal(cur->right);
if(left==2&&right==2) return 0;
if(left==0||right==0){
res++;
return 1;
}
if(left==1||right==1) return 2;
return -1;
}
int minCameraCover(TreeNode* root) {
if(traversal(root)==0) res++;
return res;
}
};