【重点!!!】【归并排序】315. 计算右侧小于当前元素的个数

发布时间:2024年01月17日

题目
归并排序的另一个经典题目:数组中的逆序对

法1:归并排序

必须掌握的基础算法!!!

class Solution {

    List<Integer> ans = new ArrayList<>();
    int[] index;    // 原数组的索引数组,存储着原数组中每个元素对应的下标
    int[] count;    // 记录题目中所求的count[i]
    int[] tmp;      // 临时数组, 存储一次归并过程中排序好的元素
    int[] tmpIndex; // 临时索引数组, 存储一次归并过程中排序好的元素对应原始索引

    //入口
    public List<Integer> countSmaller(int[] nums) {
        int n = nums.length;
        index = new int[n];
        count = new int[n];
        tmp = new int[n];
        tmpIndex = new int[n];
        for (int i = 0; i < n; i++) {
            index[i] = i;
        }
        mergeSort(nums, 0, n - 1);
        for (int i = 0; i < n; i++) {
            ans.add(count[i]);
        }
        return ans;
    }

    private void mergeSort(int[] nums, int start, int end) {
        if (start < end) {
            int mid = start + (end - start) / 2;
            mergeSort(nums, start, mid);  
            mergeSort(nums, mid + 1, end); 
            merge(nums, start, mid, end);  // 再将两个有序数组合并,只不过这里要承接统计count[i]的功能
        }
    }

    // 注意: 降序merge!!!
    private void merge(int[] nums, int start, int mid, int end) {
        int left = start;
        int right = mid + 1;
        int cur = left;

        while (left <= mid && right <= end) {
            if (nums[left] > nums[right]) {
                count[index[left]] += end - right + 1; // 右半部分小于nums[left]元素的数目
                tmpIndex[cur] = index[left];           // 记录元素位置的改变
                tmp[cur] = nums[left];
                ++left;
            } else {
                tmp[cur] = nums[right];
                tmpIndex[cur] = index[right];
                ++right;
            }
            ++cur;
        }
        while (left <= mid) {
            tmp[cur] = nums[left];
            tmpIndex[cur] = index[left];
            ++left;
            ++cur;
        }
        while (right <= end) {
            tmp[cur] = nums[right];
            tmpIndex[cur] = index[right];
            ++right;
            ++cur;
        }
        for (int i = start; i <= end; i++) {
            nums[i] = tmp[i];
            index[i] = tmpIndex[i];
        }
    }
}
文章来源:https://blog.csdn.net/Allenlzcoder/article/details/135639254
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。