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

题目链接

题目:

分析:

  • 解法一: 暴力解法, 遍历所有的数对, 找到逆序对, 需要两重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;
    }
}
相关推荐
Black蜡笔小新2 小时前
自动化AI算法训练服务器DLTM助力医学影像分析进入AI智能分析新时代
人工智能·算法·自动化
手写码匠2 小时前
深入解析大模型架构之争:全能通用模型 vs 领域专精模型
人工智能·深度学习·算法·aigc
浅念-3 小时前
LeetCode 回溯算法题——综合练习
数据结构·c++·算法·leetcode·职场和发展·深度优先·dfs
列星随旋3 小时前
线段树和树状数组的学习
学习·算法
全糖可乐气泡水5 小时前
Codex适配国产信创环境安装部署与技术适配全解析
开发语言·git·python·算法·百度
h_a_o777oah5 小时前
状态机+划分型 DP :深度解析K-划分问题下 DP 状态的转移逻辑(洛谷P2679 P2331 附C++代码)
c++·算法·动态规划·acm·状态机dp·划分型dp·滚动数组优化
05候补工程师6 小时前
从算法理想向工程现实的跨越:SLAM 核心架构、思维误区与 Nav2 实战避坑指南
人工智能·算法·安全·架构·机器人
手写码匠7 小时前
Android 17 适配实战指南:新特性解读、隐私变更与迁移全攻略
人工智能·深度学习·算法·aigc
珊瑚里的鱼7 小时前
leetcode42雨水
算法·leetcode