首页 > 试题广场 >

插入区间

[编程题]插入区间
  • 热度指数:1967 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个无重叠的,按照区间起点升序排列的区间列表,在列表中插入一个新区间,如果有原区间有重合,则合并,请返回插入后的区间列表。

数据范围:区间列表长度满足 , 区间的左右端点满足
示例1

输入

[[2,5],[6,11]],[5,6]

输出

[[2,11]]
示例2

输入

[],[2,5]

输出

[[2,5]]
class Solution {
	public Interval[] insertInterval (Interval[] intervals, Interval newInterval){
		ArrayList<Interval> list = new ArrayList<>();

		for (Interval interval : intervals) {
			if (newInterval.end < interval.start || newInterval.start > interval.end){
				list.add(interval);
			}else {
				newInterval.start = Math.min(newInterval.start, interval.start);
				newInterval.end = Math.max(newInterval.end, interval.end);
			}
		}

		list.add(newInterval);
		Interval[] array = list.toArray(new Interval[0]);

		Arrays.sort(array, (o1, o2) -> o1.start - o2.start);
		return array;
	}

}
Java解法  不相交区间正在加在返回结果中  相交的区间取[min(L1, L2), max(R1, R2)]即可
发表于 2022-04-06 20:55:33 回复(0)

import java.util.*;

/*
 * public class Interval {
 *   int start;
 *   int end;
 *   public Interval(int start, int end) {
 *     this.start = start;
 *     this.end = end;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param Intervals Interval类一维数组 
     * @param newInterval Interval类 
     * @return Interval类一维数组
     */
    public Interval[] insertInterval (Interval[] Intervals, Interval newInterval) {
        // write code here
        if(Intervals.length == 0){
            return new Interval[]{newInterval};
        }
        ArrayList<Interval> list = new ArrayList<>();
        list.add(newInterval);
        for(int i = 0; i < Intervals.length; i++){
            list.add(Intervals[i]);
        }
        // 先对所有区间按起点升序终点也升序进行二次排序,这样可以保证相同起点的区间,更大的区间在后面
        Collections.sort(list, (a, b) -> a.start != b.start? a.start - b.start: a.end - b.end);
        // 用双端链表构建一个结果集
        LinkedList<Interval> linkedlist = new LinkedList<>();
        linkedlist.add(list.get(0));
        for(int i = 1; i < list.size(); i++){
            if(list.get(i).start <= linkedlist.getLast().end){
                // 当前区间与最后一个加入的区间有重叠
                if(list.get(i).end <= linkedlist.getLast().end){
                    // 当前区间已经被前面的区间囊括
                    continue;
                }
                // 合并区间
                list.get(i).start = linkedlist.getLast().start;
                linkedlist.removeLast();
                linkedlist.add(list.get(i));
            }else{
                linkedlist.add(list.get(i));
            }
        }
        Interval[] res = new Interval[linkedlist.size()];
        Iterator<Interval> iterator = linkedlist.iterator();
        int index = 0;
        while(iterator.hasNext()){
            res[index++] = iterator.next();
        }
        return res;
    }
}

发表于 2021-12-28 22:02:36 回复(0)
一个比较容易想到的思路是:先将新的区间连同原有的区间放到一个容器里,然后按区间的起点升序,且终点也升序进行二次排序,保证对于起点相同的区间而言,大区间排在后面。排好序后就可以对容器中的区间进行合并,遍历容器,不断将当前要加入到结果集中的区间与结果集中的最后一个区间进行对比,两者有重合区域时就将结果集的末尾区间修改成范围更大的。
import java.util.*;

/*
 * public class Interval {
 *   int start;
 *   int end;
 *   public Interval(int start, int end) {
 *     this.start = start;
 *     this.end = end;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param Intervals Interval类一维数组 
     * @param newInterval Interval类 
     * @return Interval类一维数组
     */
    public Interval[] insertInterval (Interval[] Intervals, Interval newInterval) {
        // write code here
        if(Intervals.length == 0){
            return new Interval[]{newInterval};
        }
        ArrayList<Interval> list = new ArrayList<>();
        list.add(newInterval);
        for(int i = 0; i < Intervals.length; i++){
            list.add(Intervals[i]);
        }
        // 先对所有区间按起点升序终点也升序进行二次排序,这样可以保证相同起点的区间,更大的区间在后面
        Collections.sort(list, (a, b) -> a.start != b.start? a.start - b.start: a.end - b.end);
        // 用双端链表构建一个结果集
        LinkedList<Interval> linkedlist = new LinkedList<>();
        linkedlist.add(list.get(0));
        for(int i = 1; i < list.size(); i++){
            if(list.get(i).start <= linkedlist.getLast().end){
                // 当前区间与最后一个加入的区间有重叠
                if(list.get(i).end <= linkedlist.getLast().end){
                    // 当前区间已经被前面的区间囊括
                    continue;
                }
                // 合并区间
                list.get(i).start = linkedlist.getLast().start;
                linkedlist.removeLast();
                linkedlist.add(list.get(i));
            }else{
                linkedlist.add(list.get(i));
            }
        }
        Interval[] res = new Interval[linkedlist.size()];
        Iterator<Interval> iterator = linkedlist.iterator();
        int index = 0;
        while(iterator.hasNext()){
            res[index++] = iterator.next();
        }
        return res;
    }
}

发表于 2021-12-11 14:54:06 回复(0)