1. 程式人生 > 其它 >Leetcode每日一題:22/05/20:尋找右區間

Leetcode每日一題:22/05/20:尋找右區間

給你一個區間陣列 intervals ,其中 intervals[i] = [starti, endi] ,且每個 starti不同

區間 i右側區間 可以記作區間 j ,並滿足 startj`` >= endi ,且 startj 最小化

返回一個由每個區間 i右側區間 的最小起始位置組成的陣列。如果某個區間 i 不存在對應的 右側區間 ,則下標 i 處的值設為 -1

示例 1:

輸入:intervals = [[1,2]]
輸出:[-1]
解釋:集合中只有一個區間,所以輸出-1。

示例 2:

輸入:intervals = [[3,4],[2,3],[1,2]]
輸出:[-1,0,1]
解釋:對於 [3,4] ,沒有滿足條件的“右側”區間。
對於 [2,3] ,區間[3,4]具有最小的“右”起點;
對於 [1,2] ,區間[2,3]具有最小的“右”起點。

示例 3:

輸入:intervals = [[1,4],[2,3],[3,4]]
輸出:[-1,2,-1]
解釋:對於區間 [1,4] 和 [3,4] ,沒有滿足條件的“右側”區間。
對於 [2,3] ,區間 [3,4] 有最小的“右”起點。

思路:二分+排序

class Solution {
    public int[] findRightInterval(int[][] intervals) {
        int len = intervals.length;
        int[] res = new int[len];
        int[][] startAndIndex = new int[len][2];
        for (int i = 0; i < len; i++) {
            startAndIndex[i][0] = intervals[i][0];//表示區間的start
            startAndIndex[i][1] = i;//區間對應的索引
        }
        //排序,按照start從小到大排序
        Arrays.sort(startAndIndex, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o1[0] - o2[0];
            }
        });
        for (int i = 0; i < len; i++) {
            res[i] = helper(startAndIndex, intervals[i][1]);
        }
        return res;
    }
    /**
    二分法,找到右側區間的下標
     */
    private int helper(int[][] startAndIndex, int target) {
        int left = 0, right = startAndIndex.length;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (startAndIndex[mid][0] >= target) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        if (left == startAndIndex.length) {//若left一直增加,直到最大,則說明沒有符合題意的右側空間
            return -1;
        }
        return startAndIndex[left][1];
    }
}