交易逆序对的总数 ---- 分治-归并

题目链接

题目:

分析:

  • 解法一: 暴力解法, 遍历所有的数对, 找到逆序对, 需要两重for循环, 一定会超时
  • 解法二: 归并排序的思想
  • 如果我们将数组分成两半, 我们在每一半中各找一个数字, 判断是否为逆序对, 再根据归并的思想, 再将一半数组分半, 判断是否为逆序对, 直到数组只有一个元素或一个元素也没有, 此时也不具有逆序对了
  • 如果我们再对数组进行归并排序, 归并排序有一个结论就是: 如果是升序排序, 当前的cur1前面的数字和cur2前面的数字一定是都小于cur1和cur2的
  • 策略一: 升序排序, 根据后面一半的数字cur2, 找出前面一半有多少个数字比它大
    如果这时nums[cur1] > nums[cur2] , 说明cur1前面的数字都不可能比cur2大, 而cur1后面的数字包括cur1都是比cur2大的, 所以我们可以利用升序排序, 轻松的找到多个逆序对, 即cur1到mid, 然后由于是升序, 需要将cur2放在tmp数组中, cur2++
    如果这时nums[cur1] <= nums[cur2], 说明cur1前面的数字包括cur1都不可能比cur2大, 后面的数我们还不知道, 所以只需将cur1++即可, 并在这之前根据归并排序的规则, 将此数放在tmp数组中
  • 同样, 如果是降序排序, 当前的cur1前面的数字和cur2前面的数字一定是都大于cur1和cur2的
  • 策略二: 降序排序, 根据前面一半的数字cur1, 找出后面一半有多少个数字比它小
    如果这时nums[cur1] > nums[cur2] , 说明cur2后面的数字包括cur2都比cur1小, 所以我们可以利用降序排序, 轻松的找到多个逆序对, 即cur2到right, 然后需要将cur1放在tmp数组中, cur1++
    如果这时nums[cur1] <= nums[cur2], 说明cur2前面的数字包括cur2都比cur1大,, 而cur2后面的数字还不知道, 然后由于是降序, 需要将cur2放在tmp数组中, cur2++

代码:

java 复制代码
class Solution {
    int[] tmp;

    public int reversePairs(int[] record) {
        tmp = new int[record.length];
        return mergeSort(record, 0, record.length - 1);
    }

    public int mergeSort(int[] nums, int left, int right) {
        if (left >= right)
            return 0;
        int ret = 0;
        int mid = left + ((right - left) >> 1);
        ret += mergeSort(nums, left, mid);
        ret += mergeSort(nums, mid + 1, right);
        int cur1 = left;
        int cur2 = mid + 1;
        int i = 0;
        while (cur1 <= mid && cur2 <= right) {
            if (nums[cur1] <= nums[cur2]) {
                tmp[i++] = nums[cur1++];
            } else {
                ret += mid - cur1 + 1;
                tmp[i++] = nums[cur2++];
            }
        }
        while (cur1 <= mid) {
            tmp[i++] = nums[cur1++];
        }
        while (cur2 <= right) {
            tmp[i++] = nums[cur2++];
        }
        for (int j = left; j <= right; j++) {
            nums[j] = tmp[j - left];
        }
        return ret;
    }
}
相关推荐
Wei&Yan5 分钟前
数据结构——顺序表(静/动态代码实现)
数据结构·c++·算法·visual studio code
团子的二进制世界39 分钟前
G1垃圾收集器是如何工作的?
java·jvm·算法
吃杠碰小鸡43 分钟前
高中数学-数列-导数证明
前端·数学·算法
故事不长丨43 分钟前
C#线程同步:lock、Monitor、Mutex原理+用法+实战全解析
开发语言·算法·c#
long31644 分钟前
Aho-Corasick 模式搜索算法
java·数据结构·spring boot·后端·算法·排序算法
近津薪荼1 小时前
dfs专题4——二叉树的深搜(验证二叉搜索树)
c++·学习·算法·深度优先
熊文豪1 小时前
探索CANN ops-nn:高性能哈希算子技术解读
算法·哈希算法·cann
熊猫_豆豆1 小时前
YOLOP车道检测
人工智能·python·算法
艾莉丝努力练剑1 小时前
【Linux:文件】Ext系列文件系统(初阶)
大数据·linux·运维·服务器·c++·人工智能·算法
偷吃的耗子2 小时前
【CNN算法理解】:CNN平移不变性详解:数学原理与实例
人工智能·算法·cnn