代码随想录算法训练营Day37|56.合并区间、738.单调递增的数字、968.监控二叉树
合并区间
56. 合并区间 - 力扣(LeetCode)
(图片来源网络,侵删)
和之前的思路类似,先创建一个ans二维数组,创建start和end来指明添加进入ans数组的区间下标,先对数组按照首元素排序从小到大排序后,根据当前元素是否小于下一个元素的第一个元素来决定将这个对ans数组进行增加、移动下标或改变end。具体代码如下。
class Solution {
public:
// 定义一个比较函数,用于sort函数,按照区间的起始点进行排序
static bool cmp(vector&a, vector&b){
return a[0] end){
// 将上一个区间加入ans中
ans.push_back(vector{begin,end});
// 更新区间的起始和结束点为当前区间的起始和结束点
begin = intervals[i+1][0];
end = intervals[i+1][1];
}
else
// 如果有重叠,更新结束点为当前区间和上一个区间结束点的较大值
end = max(intervals[i+1][1],end);
// 如果是最后一个区间,将其加入ans中
if(i == intervals.size()-2){
ans.push_back(vector{begin,end});
}
}// 返回合并后的区间
return ans;
}
};
算法的时间复杂度为O(nlogn),空间复杂度为O(n)。
代码随想录中代码
class Solution {
public:
vector merge(vector& intervals) {
vector result;
if (intervals.size() == 0) return result; // 区间集合为空直接返回
// 排序的参数使用了lambda表达式
sort(intervals.begin(), intervals.end(), [](const vector& a, const vector& b){return a[0] = intervals[i][0]) { // 发现重叠区间
// 合并区间,只更新右边界就好,因为result.back()的左边界一定是最小值,因为我们按照左边界排序的
result.back()[1] = max(result.back()[1], intervals[i][1]);
} else {
result.push_back(intervals[i]); // 区间不重叠
}
}
return result;
}
};
- 时间复杂度: O(nlogn)
- 空间复杂度: O(logn),排序需要的空间开销
单调递增的数字
738. 单调递增的数字 - 力扣(LeetCode)
贪心算法,98的最小单调递增数字为89,第一位不符合单调递增的情况,将该值--,并将后面的数字都变为9,使用字符串可以方便对数字进行处理,所以我们先将数字转换为字符串,然后寻找到第一个不符合单调递增情况的数字,之后对该数字以前的数字全部-1,保证其前几位在符合单调递增的情况下最大,最后把后面的数字全部变为9,即实现了最大的单调递增数字。
class Solution { public: int monotoneIncreasingDigits(int n) { // 将整数n转换为字符串s,以便逐位处理 string s = to_string(n); int i = 1; // 从左到右遍历字符串,直到遇到一个位置i,使得s[i-1] > s[i] // 找到需要调整的位置 while(i s[i]){ s[i - 1] -= 1; i-- ; } // 将位置i之后的所有数字都置为'9',这样可以保证这些位置的数字是最大的 for(int j = i + 1; j时间复杂度为O(n),空间复杂度为O(n)。
监控二叉树
968. 监控二叉树 - 力扣(LeetCode)
我开始的想法是用一个层序遍历,然后将偶数层的节点相加得到监控的数目,有些问题,后面再改改。(能力不够,先跳过吧)
class Solution { public: int minCameraCover(TreeNode* root) { queue queue; if(root!=nullptr){ queue.push(root); } int count = 0; int flag = 0; TreeNode*cur = root; vectorans; while(!queue.empty()){ int size = queue.size(); ans.push_back(size); for(int i = 0; i left){ queue.push(cur->left); } if(cur->right){ queue.push(cur->right); } } } if(ans.size() left); // 左 int right = traversal(cur->right); // 右 // 情况1 // 左右节点都有覆盖 if (left == 2 && right == 2) return 0; // 情况2 // left == 0 && right == 0 左右节点无覆盖 // left == 1 && right == 0 左节点有摄像头,右节点无覆盖 // left == 0 && right == 1 左节点有无覆盖,右节点摄像头 // left == 0 && right == 2 左节点无覆盖,右节点覆盖 // left == 2 && right == 0 左节点覆盖,右节点无覆盖 if (left == 0 || right == 0) { result++; return 1; } // 情况3 // left == 1 && right == 2 左节点有摄像头,右节点有覆盖 // left == 2 && right == 1 左节点有覆盖,右节点有摄像头 // left == 1 && right == 1 左右节点都有摄像头 // 其他情况前段代码均已覆盖 if (left == 1 || right == 1) return 2; // 以上代码我没有使用else,主要是为了把各个分支条件展现出来,这样代码有助于读者理解 // 这个 return -1 逻辑不会走到这里。 return -1; } public: int minCameraCover(TreeNode* root) { result = 0; // 情况4 if (traversal(root) == 0) { // root 无覆盖 result++; } return result; } };算法时间复杂度为O(n),空间复杂度O(n)。
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!
