剑指 Offer II 074. 合并区间(56. 合并区间)

题目:

 

思路:

【1】错误的尝试

【2】不进行排序该如何正确的处理

【3】进行排序的处理

代码展示:

进行排序的处理:

//时间5 ms击败90.74%
//内存44.4 MB击败16.45%
//时间复杂度:O(nlog⁡n),其中 n 为区间的数量。
//除去排序的开销,我们只需要一次线性扫描,所以主要的时间开销是排序的 O(nlog⁡n)。
//空间复杂度:O(log⁡n),其中 n 为区间的数量。这里计算的是存储答案之外,使用的额外空间。
//O(log⁡n) 即为排序所需要的空间复杂度。
class Solution {
    public int[][] merge(int[][] intervals) {
        if (intervals.length == 0) return new int[0][2];
        //这种是lambda表达式展开前的原本写法
//        Arrays.sort(intervals,new Comparator<int[]>() {
//                    public int compare(int[] interval1, int[] interval2) {
//                        return interval1[0] - interval2[0];
//                    }
//                });
        Arrays.sort(intervals, (intVal1, intVal2) -> intVal1[0] - intVal2[0]);
        List<int[]> merged = new ArrayList<int[]>();
        for (int i = 0; i < intervals.length; ++i) {
            int L = intervals[i][0], R = intervals[i][1];
            if (merged.size() == 0 || merged.get(merged.size() - 1)[1] < L) {
                merged.add(new int[]{L, R});
            } else {
                merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], R);
            }
        }
        return merged.toArray(new int[merged.size()][]);
    }
}

 

不进行排序该如何正确的处理:

//时间1 ms击败100%
//内存43.9 MB击败86.6%
class Solution {
    public int[][] merge(int[][] intervals) {
        int maxValue = 0;
        //遍历找到结束最大值
        for (int i = 0; i < intervals.length; i++) {
            if (intervals[i][1] > maxValue) {
                maxValue = intervals[i][1];
            }
        }
        maxValue++; //最大值加1
        int[] startSide = new int[maxValue]; //根据最大值 创建数组,默认0
        boolean[] help = new boolean[maxValue]; //根据最大值 创建数组,默认false
        for (int[] v : intervals) { //遍历二维数组,命中起始值该下标值设为1,每出现一次加1,命中结束值该下标值设为-1,每出现一次-1
            startSide[v[0]] += 1;
            startSide[v[1]] -= 1;
            //为了防止起始值和结束值为同一个值
            if (v[0] == v[1]) { //如果起始值=结束值,那么该位置赋值true
                help[v[0]] = true;
            }
        }
        ArrayList<int[]> ans = new ArrayList<>();
        int startValue = -1;
        int endValue;
        int sumValue = 0; //累加值
        for (int i = 0; i < maxValue; i++) { //遍历到最大值
            if (startSide[i] != 0) { //当数值不为0时参与计算考虑,大于0为起始数字,小于0为结束数字,当和为0时那么一个闭合完成。
                sumValue += startSide[i];
                if (startValue == -1 && sumValue > 0) { //当没有起始数字时,且和值大于0说明第一次出现起始数字
                    startValue = i;
                }
                if (sumValue == 0) { //当和值等于0说明最后一次出现结束数字
                    endValue = i;
                    ans.add(new int[]{startValue, endValue});
                    //重置起始数字
                    startValue = -1;
                }
            } else {
                if (help[i]  && sumValue == 0) {
                    ans.add(new int[]{i, i});
                }
            }
        }
        return ans.toArray(new int[ans.size()][]);
    }
}

 

错误的尝试:

class Solution {
    public int[][] merge(int[][] intervals) {
        LinkedList<int[]> result = new LinkedList<>();
        int[] temp = null;
        for (int[] data : intervals){
            if (temp == null) {
                temp = data;
                continue;
            }
            // 需要考虑的情况:要么是temp的最大值在data的区间内,要么是data的最大值在temp的区间内,都代表着两者重合
            // 1.[1,4],[0,4]
            // 2.[2,3],[4,5],[6,7],[8,9],[1,10]
            // 3.[2,3],[5,5],[2,2],[3,4],[3,4] //这种无序的间隔着实难搞,不得不要进行排序
            if ((temp[1] >= data[0] && temp[1]<= data[1]) || (data[1] >= temp[0] && data[1]<= temp[1])){
                int min = Math.min(temp[0],data[0]);
                int max = Math.max(temp[1],data[1]);

                //针对情况2,进行向上合并
                int[] last_arr = result.peekLast();
                while (!result.isEmpty() && ((max >= last_arr[0] && max<= last_arr[1]) || (last_arr[1] >= min && last_arr[1]<= max))){
                    last_arr = result.pollLast();
                    min = Math.min(min,last_arr[0]);
                    max = Math.max(max,last_arr[1]);
                }
                temp = new int[]{min,max};
                continue;
            }
            result.add(temp);
            temp = data;
        }
        if (temp != null) result.add(temp);
        int[][] res = new int[result.size()][2];
        for (int i = 0; i < result.size(); i++){
            int[] data = result.get(i);
            res[i] = data;
        }
        return res;
    }
}

 

posted @ 2023-03-29 14:28  忧愁的chafry  阅读(12)  评论(0编辑  收藏  举报