精品推荐:
清华算是中国的最高学府,一般来说清华毕业工作应该是不愁找的。可是最近在网上看到一清华学生发文称,找了一堆工作都不要,最后只有外包给了offer,先凑合干吧。
互联网行业就算在卷也不可能卷到清华毕业都找不到工作,这很可能是要求太高了,或者要价太高了,不管怎样有份工作先干着在说吧。
网友评论:
--------------下面是今天的算法题--------------
来看下今天的算法题,这题是LeetCode的第56题:合并区间。
问题描述
来源:LeetCode第56题
难度:中等
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
示例1:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例2:
输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
1 <= intervals.length <= 10^4
intervals[i].length == 2
0 <= starti <= endi <= 10^4
问题分析
这题让合并区间,并且合并之后的区间没有重叠,实际上就是让把重叠的区间给合并,怎么判断区间有没有重叠呢?我们以示例一为例画个图来看下。
如上图所示,要判断两个区间有没有重叠,我们先对所有区间按照起始点进行排序,排序之后如果后面区间的起始点小于前面区间的终止点,比如区间[2,6]和区间[1,3],那么这两个区间肯定有重叠,我们需要把他俩合并即可,合并之后的区间是[1,6],然后这个区间还要继续和后面的区间比较。
如果后面区间的起始点大于前面区间的终止点,比如上面合并之后的区间[1,6]和区间[8,10],那么这两个区间肯定是没有重叠的,我们需要把前面的区间[1,6]添加到集合中,后面的区间[8,10]先不要添加,因为后面还需要查找和[8,10]有没有重叠的区间。
JAVA:
public int[][] merge(int[][] intervals) {
// 按照起始点对数组进行排序
Arrays.sort(intervals, Comparator.comparingInt(a -> a[0]));
int start = intervals[0][0];
int end = intervals[0][1];
List<int[]> ans = new ArrayList<>();
for (int[] interval : intervals) {
if (interval[0] <= end) {// 当前区间和前面区间合并
end = Math.max(end, interval[1]);
} else {// 当前区间和前面区间不能合并,把前面的区间添加进来。
ans.add(new int[]{start, end});
start = interval[0];
end = interval[1];
}
}
ans.add(new int[]{start, end});// 最后的区间要单独添加。
// 把集合转为数组。
return ans.toArray(new int[ans.size()][]);
}
C++:
public:
vector<vector<int>> merge(vector<vector<int>> &intervals) {
// 按照起始点对数组进行排序
sort(intervals.begin(), intervals.end());
int start = intervals[0][0];
int end = intervals[0][1];
vector<vector<int>> ans;
for (vector<int> &interval: intervals) {
if (interval[0] <= end) {// 当前区间和前面区间合并
end = max(end, interval[1]);
} else {// 当前区间和前面区间不能合并,把前面的区间添加进来。
ans.push_back({start, end});
start = interval[0];
end = interval[1];
}
}
ans.push_back({start, end});// 最后的区间要单独添加。
return ans;
}
Python:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
# 按照起始点对数组进行排序
intervals.sort(key=lambda x: x[0])
ans = []
start, end = intervals[0][0], intervals[0][1]
for interval in intervals:
if interval[0] <= end: # 当前区间和前面区间合并
end = max(end, interval[1])
else: # 当前区间和前面区间不能合并,把前面的区间添加进来。
ans.append([start, end])
start = interval[0]
end = interval[1]
ans.append([start, end]) # 最后的区间要单独添加。
return ans
笔者简介
博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解800多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。