题目描述:
给出一个无重叠的 ,按照区间起始端点排序的区间列表。
在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。
示例 1:
输入: intervals = [[1,3],[6,9]], newInterval = [2,5]
输出: [[1,5],[6,9]]
示例 2:
输入: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
输出: [[1,2],[3,10],[12,16]]
解释: 这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。
本想的是把每个点存储起来,然后放入,但是超时。。。
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
List<int[]> list = new ArrayList<>();
int start = Integer.MAX_VALUE;
int end = Integer.MIN_VALUE;
if (newInterval[0] == newInterval[1]) {
for (int[] is : intervals) {
list.add(is);
}
list.add(newInterval);
int[][] result = new int[list.size()][2];
for (int i = 0; i < result.length; i++) {
result[i] = list.get(i);
}
Arrays.sort(result, new Comparator<int[]>() {
public int compare(int[] a, int[] b) {
return a[0] - b[0];
}
});
return result;
}
Set<Integer> set = new HashSet();
for (int[] integer : intervals) {
int temstart = integer[0];
int temend = integer[1];
start = Math.min(temstart, start);
end = Math.max(end, temend);
for (int i = temstart; i < temend; i++) {
set.add(i);
}
if(temstart == temend){
list.add(integer);
}
}
// 加入新增的区间
for (int i = newInterval[0]; i < newInterval[1]; i++) {
set.add(i);
}
start = Math.min(newInterval[0], start);
end = Math.max(end, newInterval[1]);
System.out.println(set);
for (int i = start; i < end; i++) {
if (set.remove(i)) {
int temshuzu[] = new int[2];
int tem = i;
while (set.remove(tem - 1)) {
tem--;
}
temshuzu[0] = tem;
tem = i;
while (set.remove(tem + 1)) {
tem++;
}
temshuzu[1] = tem + 1;
list.add(temshuzu);
}
}
int[][] result = new int[list.size()][2];
for (int i = 0; i < result.length; i++) {
result[i] = list.get(i);
}
Arrays.sort(result, new Comparator<int[]>() {
public int compare(int[] a, int[] b) {
return a[0] - b[0];
}
});
return result;
}
}
使用二分查找法
思路是先找到要插入的地方,然后向后合并,再向前合并
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
if (intervals == null || intervals.length == 0) {
return new int[][] {newInterval};
}
// 二分查找找到最后一个intervals[i][0]小于newInterval[0]的位置
int index = searchLastLessThan(intervals, newInterval);
ArrayList<int[]> list = new ArrayList<>();
// newInterval插入到头部
if (index < 0) {
list.add(new int[] {newInterval[0], newInterval[1]});
} else {
// 把前半部分加入list中
for (int i = 0; i <= index; i++) {
list.add(new int[] {intervals[i][0], intervals[i][1]});
}
// 将newInterval插入
int[] inter = list.get(list.size() - 1);
if (inter[1] < newInterval[0]) {
list.add(new int[] {newInterval[0], newInterval[1]});
} else {
inter[1] = Math.max(inter[1], newInterval[1]);
}
}
// 合并后半部分
for (int i = index + 1; i < intervals.length; i++) {
int[] inter = list.get(list.size() - 1);
if (inter[1] < intervals[i][0]) {
list.add(new int[] {intervals[i][0], intervals[i][1]});
} else {
inter[1] = Math.max(intervals[i][1], inter[1]);
}
}
// 转换结果返回
int[][] res = new int[list.size()][2];
for (int i = 0; i < list.size(); i++) {
res[i][0] = list.get(i)[0];
res[i][1] = list.get(i)[1];
}
return res;
}
private int searchLastLessThan(int[][] intervals, int[] newInterval) {
int left = 0, right = intervals.length - 1, res = -1, mid;
while (left <= right) {
mid = left + ((right - left) >> 1);
if (intervals[mid][0] > newInterval[0]) {
right = mid - 1;
} else {
if (mid == intervals.length - 1 || intervals[mid + 1][0] > newInterval[0]) {
res = mid;
break;
}
left = mid + 1;
}
}
return res;
}
}
或者借鉴这个思路
public int[][] insert(int[][] intervals, int[] newInterval){
List<int[]> res = new LinkedList<int[]>();
int i = 0;
int n = intervals.length;
int nStart = newInterval[0];
int nEnd = newInterval[1];
//当前区间的end 小于 插入区间的 start,跳过并加入结果集
while(i < n && intervals[i][1] < newInterval[0]) {
res.add(intervals[i]);
i++;
}
//如果到最后都没找到,把newInterval加到最后
if(i == n) {
res.add(newInterval);
return res.toArray(new int[0][]);
}
//选择小的 作为新区的 start
nStart = Math.min(intervals[i][0],newInterval[0]);
//如果当前的start < end 把当前end 和 newInterval的end 比较
while(i < n && intervals[i][0] <= newInterval[1]) {
nEnd = Math.max(newInterval[1], intervals[i][1]);
i++;
}
res.add(new int[]{nStart,nEnd});
//如果后面有没遍历到的 加入最后的结果
while(i < n) {
res.add(intervals[i++]);
}
for(int[] x : res) {
System.out.println(x[0]+"------"+x[1]);
}
return res.toArray(new int[0][]);
}
作者:chen4547
链接:https://leetcode-cn.com/problems/two-sum/solution/java-by-chen4547/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。