• LCR 170. 交易逆序对的总数(C语言+分治递归)


    1. 题目

            在股票交易中,如果前一天的股价高于后一天的股价,则可以认为存在一个「交易逆序对」。请设计一个程序,输入一段时间内的股票交易记录 record,返回其中存在的「交易逆序对」总数。

    2. 输入输出样例

            示例1

    1. 输入:record = [9, 7, 5, 4, 6]
    2. 输出:8
    3. 解释:交易中的逆序对为 (9, 7), (9, 5), (9, 4), (9, 6), (7, 5), (7, 4), (7, 6), (5, 4)。

            限制

    0 <= record.length <= 50000

    3. 实现思路

             使用分治和归并排序的方法来计算整数数组中的逆序对数量,主要的思路是:

            (1)将数组分解为两个子数组;

            (2)递归地计算每个子数组的逆序对数量;

            (3)在归并的过程中,统计两个子数组之间的逆序对数量,并将子数组合并成一个有序的数组;

            (4)通过递归和归并的结合,得出整个数组中的逆序对数量。

    623ccf339ef74d5388d687de9e04f9c6.jpg

    • 分解阶段:将数组分解为两个子数组,这个过程需要 O(1) 的时间。
    • 递归计算阶段:递归地计算左子数组和右子数组的逆序对数量,每次递归都将数组大小减半。因为有 log₂(n) 层递归,每层的时间复杂度是 O(n),所以总的时间复杂度是 O(nlogn)。
    • 归并阶段:在归并的过程中,需要线性时间 O(n) 来合并两个有序子数组。因为在每层递归中都会执行这个操作,总的时间复杂度是 O(nlogn)。
    •  综合以上三个阶段,总的时间复杂度是 O(nlogn)。

    4. 实现代码 

    1. // 定义递归函数 nxs,用于计算逆序对数量
    2. int nxs(int* nums, int l, int r){
    3. // 如果子数组的左边界大于或等于右边界,说明子数组中没有元素或只有一个元素,逆序对数量为0
    4. if(l >= r){
    5. return 0;
    6. }
    7. // 分解:将当前数组划分为两个子数组
    8. int mid = (l + r) / 2;
    9. int tl = nxs(nums, l, mid); // 递归计算左子数组中的逆序对数量
    10. int tr = nxs(nums, mid + 1, r); // 递归计算右子数组中的逆序对数量
    11. // 求和(采用归并排序的思想)
    12. int i = l, j = mid + 1, k = 0, count = 0;
    13. int *B = (int*)malloc(sizeof(int) * (r - l + 1)); // 创建一个临时数组 B 存储归并后的结果
    14. // 归并过程
    15. while(i <= mid && j <= r){
    16. if(nums[i] > nums[j]){
    17. B[k++] = nums[j++];
    18. count += (mid - i + 1); // 如果 nums[i] > nums[j],则说明 nums[i] 及其后面的元素都与 nums[j] 构成逆序对
    19. }
    20. else{
    21. B[k++] = nums[i++];
    22. }
    23. }
    24. // 处理剩余元素
    25. while(i <= mid){
    26. B[k++] = nums[i++];
    27. }
    28. while(j <= r){
    29. B[k++] = nums[j++];
    30. }
    31. // 将归并后的结果复制回原数组 nums
    32. i = l, j = 0;
    33. while(j < k){
    34. nums[i++] = B[j++];
    35. }
    36. // 返回当前子数组中的逆序对数量
    37. return tl + count + tr;
    38. }
    39. // 主函数,调用 nxs 函数来计算整个数组中的逆序对数量
    40. int reversePairs(int* nums, int numsSize){
    41. return nxs(nums, 0, numsSize - 1);
    42. }

     

    LCR 170. 交易逆序对的总数 - 力扣(LeetCode)https://leetcode.cn/problems/shu-zu-zhong-de-ni-xu-dui-lcof/

     

  • 相关阅读:
    php 递归方式 计算学生寝室分配问题 算法
    【C++】一文解析std::binary_function、std::bind1st、std::bind2nd、std::bind
    【OpenGL】四、坐标系统和摄像机
    第15章 注销器实现原理与触发
    数据库连接性比较:Navicat 和基于 Java 的工具
    Shiro 登录认证源码详解
    Springboot自定义@Import自动装配
    SpringBoot+SpringMVC+MybatisPlus
    Win11怎么安装语音包?Win11语音包安装教程
    sqlserver修改decimal类型的长度
  • 原文地址:https://blog.csdn.net/qq_51167531/article/details/133365762