星海横流,岁月成碑。转眼之间,算法训练营的进程已经过半,而我也在日复一日的坚持中,找寻到了对算法的热爱。
56 合并区间
这题和前面的射爆气球等题目比较像,难度也不大,都是先按第一个元素排序后,从第一个子数组开始遍历,如果当前的子数组的第二个元素大于后一个数组的第一个元素,就更新right,反之则将当前的left和right存入数组。
738单调递增的数字
这道题如果用暴力解法会TLE,所以需要考虑其它解法。贪心的解法非常巧妙,是从后向前遍历,如果遇到高位数字大于低位数字,就将高位数字-1,同时将所有低位数字都为9.
int i=str.size()-1;
int flag=str.size()-1;
while(i>0){if(str[i-1]>str[i]) {str[i-1]--;flag=i;
}
for(int j=flag;j<str.size();j++){str[j]=9;
}
这道题的另一个难点是int和string类型的相互转化,int转化为string要用to_string函数,string转为int要用stoi函数。
968监控二叉树
这道题就比较难了,是二叉树和贪心的结合。要使摄像头数最少,就是在所有叶子节点都不放摄像头,局部最优是让叶子节点的父节点安装摄像头,全局最优是使摄像头数最少。所以这题需要隔两层放一个摄像头。如何隔两层放一个摄像头呢?这时就需要状态转移公式。考虑用0,1,2来表示不同的状态。0表示没有被检测到,1表示放置摄像头,2表示有被摄像头检测到,然后分类讨论即可。对于空节点,可以用反证法证明要返回的值是2,这样才能保证在叶子结点的父节点放置摄像头。这样遍历还会漏掉一种情况,就是当如下图情况时,根节点的左孩子返回值为2,右孩子返回值也为2,按照这样遍历的方法,根节点返回值为0,就不会在根节点添加摄像头。因此,需要在主函数中对这种情况额外做一个判断
int minCameraCover(TreeNode* root) {int temp=traversal(root);if(temp==0) res++;return res;}