327. 區間和的個數 (歸併排序)

lankerens發表於2020-11-28

LeetCode: 327. 區間和的個數

在這裡插入圖片描述


上篇是暴力字首和 >> 時間複雜度 O ( n 2 ) O(n^2) O(n2)
部落格指路: 327. 區間和的個數 (暴力字首和)


歸併排序解法 優化 >> 時間複雜度 O ( n l o g n ) O(nlogn) O(nlogn)

思路:

在這裡插入圖片描述



  1. 核心程式碼
  2. 合 (區域性排序)


歸併排序

class Solution {
    public int countRangeSum(int[] nums, int lower, int upper) {
        int len = nums.length;
        if(len == 0) return 0;
        long[] pre = new long[len + 1];
        // 必然
        pre[0] = 0;
        for (int i = 1; i < pre.length; i++) {
            pre[i] = pre[i - 1] + nums[i - 1];
        }

        int ans = divde(pre, 0, pre.length - 1, lower, upper);
        return ans;
    }

    public int divde(long[] arr, int left, int right, int lower, int upper){
        // 終止條件
        if(left == right) return 0;
        int mid = left + (right - left) / 2;

        // 分
        int n1 = divde(arr, left, mid, lower, upper);
        int n2 = divde(arr, mid + 1, right, lower, upper);
        int ans = n1 + n2;

        // 排序處理後 
        // 核心程式碼
        int cnt = left;
        int i = mid + 1;
        int j = mid + 1;

        while(cnt <= mid){
            
            // 找到左邊界
            while(i <= right && arr[i] - arr[cnt] < lower){
                i++;
            }
            while(j <= right && arr[j] - arr[cnt] <= upper){
                j++;
            }
            ans += j - i;
            cnt++;
        }


        // 合
        long[] sorted = new long[right - left + 1];
        int a = left, b = mid + 1;
        int index = 0; 
        while(a < mid + 1 || b <= right){
            if(a > mid){
                sorted[index++] = arr[b++];
            }else if(b > right){
                sorted[index++] = arr[a++];
            }else {
                // 
                if(arr[a] > arr[b]){
                    sorted[index++] = arr[b++];
                }else {
                    // 小於等於
                    sorted[index++] = arr[a++];
                }
            }
        }
        
        // 更新原陣列
        for (int k = 0; k < sorted.length; k++) {
            arr[left + k] = sorted[k];
        }

        return ans;
    }   

}






官方題解: 區間和的個數

相關文章