当前位置: 首页 > article >正文

【C++算法】48.分治_归并_数组中的逆序对

文章目录

    • 题目链接:
    • 题目描述:
    • 解法
    • C++ 算法代码:
    • 图解


题目链接:

剑指 Offer 51. 数组中的逆序对


题目描述:

bf1b557f6a2272923867b79316744c72


解法

解法一:暴力解法:暴力枚举

两层for循环

本题不能用,用了会超时。

解法二:

归并排序

c54f5e37f66b8dee89f4fb6dba821c7b


C++ 算法代码:

class Solution 
{
    int tmp[50010]; // 用于在归并过程中临时存储排序后的元素
    public:
    int reversePairs(vector<int>& nums) 
    {
        return mergeSort(nums, 0, nums.size() - 1); //返回逆序对的数量
    }
    int mergeSort(vector<int>& nums, int left, int right)
    {
        if(left >= right) return 0; // 基本情况:区间内只有一个元素或为空,没有逆序对
        int ret = 0; // 用于存储当前区间内的逆序对数量
        // 1. 找中间点,将数组分成两部分
        int mid = (left + right) >> 1; // 使用位运算 (left + right) / 2 提高效率
        // [left, mid][mid + 1, right]
        // 2. 递归地对左右两个子区间进行排序,并计算逆序对数量
        // 左边的个数 + 排序 + 右边的个数 + 排序 
        v // 右半部分的逆序对
        // 3. 计算跨越左右两个子区间的逆序对数量
        // cur1指向第一个子数组的当前元素
        // cur2指向第二个子数组的当前元素
        // i指向临时数组的当前位置
        int cur1 = left, cur2 = mid + 1, i = 0;
        // 当两个子数组都还有元素时,比较并处理
        while(cur1 <= mid && cur2 <= right) // 升序的时候
        {
            if(nums[cur1] <= nums[cur2])
            {
                tmp[i++] = nums[cur1++];
            }
            else
            {
                // 当 nums[cur1] > nums[cur2] 时,说明 cur1 到 mid 之间的所有元素都大于 nums[cur2]
                // 因此,逆序对的数量为 mid - cur1 + 1
                ret += mid - cur1 + 1;
                tmp[i++] = nums[cur2++];
            }
        }
        // 4. 处理一下排序
        while(cur1 <= mid) tmp[i++] = nums[cur1++];
        while(cur2 <= right) tmp[i++] = nums[cur2++];
        // 5. 将临时数组中的合并结果复制回原数组的对应位置
        for(int j = left; j <= right; j++)
            nums[j] = tmp[j - left];

        return ret; // 返回当前区间内的逆序对总数
    }
};

图解

例如:nums = [9, 7, 5, 4, 6]

7f783442905ae0d00975ae6f42ad1b8c

  1. mergeSort(nums, 0, nums.size() - 1);->mergeSort(nums, 0, 4);

    ret = 0;mid = 2;

    ret += mergeSort(nums, left, mid);->ret += mergeSort(nums, 0, 2);

3309f512ac83b462e19c9b3a8eee59a6

  1. mergeSort(nums, 0, 2);

    ret = 0;mid = 1;

    ret += mergeSort(nums, left, mid);->ret += mergeSort(nums, 0, 1);

9624d3e24c19a45a8ddde35ef51d8e3a

  1. mergeSort(nums, 0, 1);

    ret = 0;mid = 0;

    ret += mergeSort(nums, left, mid);->ret += mergeSort(nums, 0, 0);

da07bddc53bd6f027b99b8dc0ae44d46

  1. mergeSort(nums, 0, 0);

    left = right -> return 0;

2ccef53a2b3792b7a6a65705f6ef7e77

  1. ret = 0;

    ret += mergeSort(nums, mid + 1, right);->ret += mergeSort(nums, 1, 1);

a3a116993342ebe207a789df1c181b74

  1. mergeSort(nums, 1, 1);

    left = right -> return 0;

c1404ba581d5063203b6ad151baa897e

  1. mergeSort(nums, 0, 1);

    ret = 0;mid = 0;

    cur1=0;cur2=1;i=0

    进入while循环

    ret += mid - cur1 + 1;->ret += 0- 0+ 1=1
    tmp[i++] = nums[cur2++];->tmp[0] = nums[1];->tmp[0]=7

    i=1;cur2=2,跳出while循环

    cur1<mid,tmp[i++] = nums[cur1++];->tmp[1] = nums[0];->tmp[1]=9

    i=2;cur1=1

    进入for循环

    nums[0]=7

    nums[1]=9

    return 1

    0f4a6e536834de2512abf1e2eb666a97

  2. mergeSort(nums, 0, 2);

    ret = 1;mid = 1;

    ret += mergeSort(nums, mid + 1, right);->ret += mergeSort(nums, 2, 2);

    4875e3302d5daa66e808568d83d4650e

  3. mergeSort(nums, 2, 2);

    left = right -> return 0;

    6313d64c80c2ca28b8fde3bd786e7fc5

  4. mergeSort(nums, 0, 2);

    ret = 1;mid = 1;

    cur1=0;cur2=2;i=0

    进入while循环

    ret += mid - cur1 + 1;->ret = ret + 1- 0+ 1=3
    tmp[i++] = nums[cur2++];->tmp[0] = nums[2];->tmp[0]=5

    i=1;cur2=3,跳出while循环

    cur1<=mid,tmp[i++] = nums[cur1++];->tmp[1] = nums[0];->tmp[1]=7

    i=2;cur1=1

    cur1<=mid,tmp[i++] = nums[cur1++];->tmp[2] = nums[1];->tmp[2]=9

    i=3;cur1=2

    进入for循环

    nums[0]=5

    nums[1]=7

    nums[2]=9

    return 3

    3513f7c729ea4a29588f43ca5fec3d45

  5. mergeSort(nums, 0, 4);

    ret = 3;mid = 2;

    ret += mergeSort(nums, mid + 1, right); ->ret += mergeSort(nums, 3, 4);

    78e4c6f18d6acf0f1dc1bd28fe55be88

  6. mergeSort(nums, 3, 4);

    ret = 3;mid = 3;

    ret += mergeSort(nums, left, mid);->ret += mergeSort(nums, 3, 3);

    28289b97440f6c1c878bebdff58d2d0c

  7. mergeSort(nums, 3, 3);

    left = right -> return 0;

    604208c48a4daa3ecbee819f4685796c

  8. mergeSort(nums, 3, 4);

    ret = 3;mid = 3;

    ret += mergeSort(nums, mid + 1, right);->ret += mergeSort(nums, 4, 4);

    dcf8a155909d2a4770cdce5737f3fa3c

  9. mergeSort(nums, 4, 4);

    left = right -> return 0;

    3a9d1646ceddd857b63f4586d5ebde39

  10. mergeSort(nums, 3, 4);

    ret = 3;mid = 3;

    cur1=3;cur2=4;i=0

    进入while循环

    tmp[i++] = nums[cur1++];->tmp[0] = nums[3];->tmp[0] = 4

    i=1;cur1=4,跳出while循环

    cur2<=right;tmp[i++] = nums[cur2++];->tmp[1] = nums[4];->tmp[1] = 6

    i=2;cur2=5

    进入for循环

    nums[3]=4

    nums[4]=6

    return 3

    4c2912cb7dbf9135797083dc13775aef

  11. mergeSort(nums, 0, 4);

    ret = 3;mid = 2;

    cur1=0;cur2=3;i=0

    进入while循环

    ret += mid - cur1 + 1;->ret = ret + 2- 0+ 1= 3 +3 =6
    tmp[i++] = nums[cur2++];->tmp[0] = nums[3];->tmp[0]=4

    i=1;cur2=4

    nums[cur1]<=nums[cur2];->tmp[i++] = nums[cur1++];->tmp[1] = nums[0];->tmp[1]=5

    i=2;cur1=1

    ret += mid - cur1 + 1;->ret = ret + 2- 1+ 1= 6 +2 =8
    tmp[i++] = nums[cur2++];->tmp[2] = nums[4];->tmp[2]=6

    i=3;cur2=5

    跳出while循环

    cur1=1,cur2=5

    cur1<=mid,tmp[i++] = nums[cur1++];->tmp[3] = nums[1];->tmp[3]=7

    i=4;cur1=2

    cur1<=mid,tmp[i++] = nums[cur1++];->tmp[2] = nums[2];->tmp[4]=9

    i=5;cur1=3

    进入for循环

    nums[0]=4

    nums[1]=5

    nums[2]=6

    nums[3]=7

    nusm[4]=9

ea7931050b984e5cd278e82fac8230c2


http://www.kler.cn/a/446244.html

相关文章:

  • BenchmarkSQL使用教程
  • OpenCV圆形标定板检测算法findGrid原理详解
  • Android Java Ubuntu系统如何编译出 libopencv_java4.so
  • LeetCode刷题day29——动态规划(完全背包)
  • 使用计算机创建一个虚拟世界
  • 远程连接:构建智能家居舒适生活
  • uniapp 图片上传功能以及给图片添加水印
  • 数据分析实战—鸢尾花数据分类
  • 诸葛智能CTO文革:放大数据价值,释放金融营销原动力
  • Day29 C++ 模板
  • day-95 定长子串中元音的最大数目
  • 计算机视觉:原理、分类与应用
  • 头歌实训数据结构与算法-图的最短路径(第2关:多源最短路径)
  • 在 C# 中加载图像而不锁定文件
  • Xcode 文件缺失:Missing submodule xxx
  • 基于Spring Boot的大学就业信息管理系统
  • MPLS小实验:静态建立LSP
  • 【Spring】Spring的模块架构与生态圈—Spring MVC与Spring WebFlux
  • thinkphp框架diygw-ui-php进销存出库记录操作
  • 基于Spring Boot的高校素拓分管理系统
  • ImageGlass:基于C#开发的轻量级、多功能的图像查看器
  • 仿途唬养车系统汽修服务小程序修车店小程序源码
  • 数据库 MYSQL的概念
  • 怎么样保持mysql和redis数据一致性
  • CLION中运行远程的GUI程序
  • Nuc9 Truenas 和 Macmini4组雷电网桥 上传速度异常 1Mbp/s 解决