day39:数组中的逆序对(归并排序)

    技术2025-03-04  33

    问题描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。 示例 1:

    输入: [7,5,6,4]输出: 5

    来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof

    注意该问题是逆序数对个数之和,如果是从小到大的数列,那么逆序数对总数为0,如果逆序数对是从大到小排列,那么逆序数对总数会是很高计算。例如【5,4,3,2,1】逆序数对总和为4+ 3 +2 + 1 =10。 问题求解使用到了归并排序,在排序整个数组的过程中将逆序的数对个数进行求解,使用递归进行归并排序,将整个数组分成两部分,分别用 i , j 指向这两个数组的起始位置,比较 nums[i]和nums[j]的大小 ,需要将小的那一个放入temp数组,如果nums[i]>nums[j],此时就意味着出现了逆序数对,注意理解的时候mid-i+1这个计算结果是在有序数组的基础上计算的,只有有序,数组中的元素才会放入到temp中,由于该过程涉及到递归,所以理解的时候要自下至上理解。如果数组有剩余部分没有遍历到,那么剩余的数组要拷贝到原始数组中。

    class Solution { public: int merge(vector<int>&nums,int l,int r) { if(l>=r) return 0; int mid=l+r >> 1; int res=merge(nums,l,mid)+merge(nums,mid+1,r); int i=l,j=mid+1; vector<int> temp; while(i<=mid&&j<=r) { if(nums[i]<=nums[j]) temp.push_back(nums[i++]); else { temp.push_back(nums[j++]); res+=mid-i+1; } } while(i<=mid) temp.push_back(nums[i++]); while(j<=r) temp.push_back(nums[j++]); i=l; for(auto x:temp) nums[i++]=x; return res; } int inversePairs(vector<int>& nums) { return merge(nums,0,nums.size()-1); } };
    Processed: 0.013, SQL: 9