算法之插入区间

插入区间

题目
插入区间
给出一个无重叠的 ,按照区间起始端点排序的区间列表。
在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。

示例 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] 重叠。

1.暴力方式

class Solution {
        public int[][] insert(int[][] intervals, int[] newInterval) {
            // 判空处理
            if(newInterval == null || newInterval.length < 2){
                return intervals;
            }
            // 数组区间为空的情况
            if(intervals == null || intervals.length == 0) {
                int[][] data = new int[1][2];
                data[0] = newInterval;
                return data;
            }
            // 获取当前插入区间的最大值和最小值
            int newMin = newInterval[0];
            int newMax = newInterval[1];
            int startp = 0, allp = 0; // startp开始到有区间的位置方便后续结合 allp 一共结合了几个区间
            int[] centerInterval = new int[2]; // 用来存放中间新合起来的区间数据
            int n = intervals.length;
            for(int i = 0; i < n; i++){
                // 判断最小值是否在范围内
                if(intervals[i][0] <= newMin && intervals[i][1] >= newMin) {
                    centerInterval[0] = intervals[i][0];
                    allp += 1;
                    // 判断最大值是否在范围内
                    if(intervals[i][1] >= newMax){
                        centerInterval[1] = intervals[i][1];
                        break; // 两个数据都找到区间了 停止遍历
                    }
                    if(newMax > intervals[i][1] && ((i+1) == n || ((i+1) <= (n-1) && intervals[i+1][0] > newMax))){
                        centerInterval[1] = newMax;
                        break;
                    }
                    continue;
                }

                // 判断最小值在区间之前 1. i=0 之前 2. i != 0 之前
                // 1.i=0 最小区间大于插入最小区间
                // 2.i不为0,
                if((i == 0 && intervals[i][0] > newMin) || (intervals[i][0] > newMin && (i-1) >= 0 && intervals[i-1][1] < newMin)) {
                    centerInterval[0] = newMin;
                    if(intervals[i][0] > newMax) {
                        centerInterval[1] = newMax;
                        break;
                    }
                    allp += 1;
                    if(intervals[i][1] >= newMax){
                        centerInterval[1] = intervals[i][1];
                        break;
                    }
                    if(((i+1) == n && newMax >= intervals[i][1]) || (newMax >= intervals[i][1] && ((i+1) <= (n-1) && intervals[i+1][0] > newMax))){
                        centerInterval[1] = newMax;
                        break;
                    }
                    continue;
                }

                // 判断最小值在区间之后 n 之后
                if(i == (n-1) && intervals[i][1] < newMin || (intervals[i][1] < newMin && (i+1) <= (n-1) && intervals[i+1][0] > newMin)) {
                    startp += 1;
                    centerInterval[0] = newMin;
                    if(i == (n-1)){
                        centerInterval[1] = newMax;
                        break;
                    } else if(intervals[i+1][0] > newMax){
                        centerInterval[1] = newMax;
                        break;
                    }
                    continue;
                }

                // 判断最大值是否在范围内
                if(intervals[i][0] <= newMax && intervals[i][1] >= newMax){
                    centerInterval[1] = intervals[i][1];
                    allp += 1;
                    break; // 已经拿到结果数据 说明开始的数据也拿到了
                }

                // 判断最大值是否在区间外
                if(((i+1) == n && newMax >= intervals[i][1]) || (newMax >= intervals[i][1] && (i+1) <= (n-1) && intervals[i+1][0] > newMax)){
                    centerInterval[1] = newMax;
                    if(intervals[i][1] < newMin){
                        startp += 1;
                        centerInterval[0] = newMin;
                        break;
                    }
                    allp += 1;
                    break;
                }

                // 数组中的整个区间都在新添加的区间中
                if(intervals[i][0] > newMin && intervals[i][1] > newMin && intervals[i][0] < newMax && intervals[i][1] < newMax){
                    allp += 1;
                    continue;
                }
                startp += 1;
                continue;
            }
            int m = n - allp + 1;
            // 上面遍历完
            int[][] result = new int[m][2];
            for(int k = 0; k < m; k++){
                if(startp < 1) {
                    if(k == 0) {
                        result[k] = centerInterval;
                    } else {
                        result[k] = intervals[allp - 1 + k];
                    }
                } else {
                    if(k <= (startp-1)){
                        result[k] = intervals[k];
                    } else if(k == startp){
                        result[k] = centerInterval;
                    } else {
                        result[k] = intervals[allp - 1 + k];
                    }
                }
            }
            return result;
        }
}

2.采用找上下区间的方式处理

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        // 判空处理
        if(newInterval == null || newInterval.length < 2){
            return intervals;
        }
        // 数组区间为空的情况
        if(intervals == null || intervals.length == 0) {
            int[][] data = new int[1][2];
            data[0] = newInterval;
            return data;
        }    
        int l = intervals.length;
        int start = 0, end = l-1;
        // 找出下区间
        while(start < l && intervals[start][1] < newInterval[0]) {
            start++;
        }
        // 找出上区间
        while(end >= 0 && intervals[end][0] > newInterval[1]) {
            end--;
        }
        int numl = l - (end-start);
        int[][] result = new int[numl][2];
        for(int i = 0; i < numl; i++){
            if(i < start) {
                result[i] = intervals[i];
            } else if(i == start){
                int[] data = new int[2];
                if((l-1) < start) {
                    data = newInterval;
                } else if (end == -1){
                    data = newInterval;
                } else {
                    data[0] = intervals[start][0] < newInterval[0] ? intervals[start][0] : newInterval[0];
                    data[1] = intervals[end][1] > newInterval[1] ? intervals[end][1] : newInterval[1];
                }
                result[i] = data;
            } else {
                result[i] = intervals[(end-start) + i];
            }
        }
        return result;
    }
}

仅记录。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值