归并排序及其衍生问题 Merge-Sort related issue

    xiaoxiao2022-07-02  118

    归并排序及其衍生问题 Merge-Sort related issue

    #算法导论习题2-4 求逆序对的问题; Leetcode: 315. Count of Smaller Numbers After Self 327. Count of Range Sum 493.Reverse Pairs

    A[i…j], 以上问题暴力求解,遍历数组,对于k属于[i,j],k之前大于A[k]的值,需要二次遍历,因此时间复杂度O(n); 此处也可以引入二叉搜索树 将search复杂度降为O(logn); 但该方法不是本次所讨论的,本文说明如何用Merge Sort思想解决相关问题;

    对于上述问题,均可以采用divide and conquer的思想,将问题一分为二,数组分为左半部分和右半部分,分别进行求解以及排序,求解以及合并时间复杂度O(n),总的复杂度为O(nlogn);

    public List<Integer> countSmaller(int[] nums) { int n = nums.length; List<Integer> res = new ArrayList<>(); if (n == 0) return res; Integer[] arr = new Integer[n]; Arrays.fill(arr, 0); int[] index = new int[n]; for (int i = 0; i < n; i++) { index[i] = i; } countSmaller(nums, index, 0, n - 1, arr); return Arrays.asList(arr); } private void countSmaller(int[] nums, int[] index, int left, int right, Integer[] arr) { if (left >= right) return; int mid = left + ((right - left) >> 1); countSmaller(nums, index, left, mid, arr); countSmaller(nums, index, mid + 1, right, arr); int i = left; int j = mid + 1; int p = 0; int[] newIndex = new int[right - left + 1]; while (i <= mid) { while (j <= right && nums[index[i]] > nums[index[j]]) { newIndex[p++] = index[j++]; } arr[index[i]] += j - (mid + 1); newIndex[p++] = index[i++]; } while (j <= right) newIndex[p++] = index[j++]; for (i = left; i <= right; i++) { index[i] = newIndex[i - left]; } }
    最新回复(0)