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

题目链接

题目:

分析:

  • 解法一: 暴力解法, 遍历所有的数对, 找到逆序对, 需要两重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;
    }
}
相关推荐
Dr.9278 分钟前
1-10 目录树
java·数据结构·算法
子豪-中国机器人20 分钟前
C++ 蓝桥 STEMA 省选拔赛模拟测试题(第一套)
开发语言·c++·算法
callJJ22 分钟前
Bellman - Ford 算法与 SPFA 算法求解最短路径问题 ——从零开始的图论讲解(4)
数据结构·算法·蓝桥杯·图论·单源最短路径·bellman- ford算法
圈圈编码25 分钟前
LeetCode Hot100刷题——轮转数组
java·算法·leetcode·职场和发展
金融小师妹5 小时前
应用BERT-GCN跨模态情绪分析:贸易缓和与金价波动的AI归因
大数据·人工智能·算法
广州智造5 小时前
OptiStruct实例:3D实体转子分析
数据库·人工智能·算法·机器学习·数学建模·3d·性能优化
Trent19857 小时前
影楼精修-肤色统一算法解析
图像处理·人工智能·算法·计算机视觉
feifeigo1237 小时前
高光谱遥感图像处理之数据分类的fcm算法
图像处理·算法·分类
北上ing8 小时前
算法练习:19.JZ29 顺时针打印矩阵
算法·leetcode·矩阵
.格子衫.9 小时前
真题卷001——算法备赛
算法