题解 | #数组中的逆序对#
数组中的逆序对
https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=295&tqId=23260&ru=/exam/oj&qru=/ta/format-top101/question-ranking&sourceUrl=%2Fexam%2Foj
class Solution {
private:
vector<int> vv;
public:
long int fun(vector<int>& nums,int low,int high)
{
if(low>=high)
return 0;
int mid = (low+high)/2;
long left_count = fun(nums,low,mid);
long right_count = fun(nums,mid+1,high);
long mid_count = 0;
int i=low,j=mid+1;
int vvi=0;
while(i<=mid && j<= high)
{
if(nums[i]< nums[j])
{
vv[vvi++] = nums[i++];
}
else {
vv[vvi++] = nums[j++];
mid_count += mid - i +1; // 核心
}
}
while(i<=mid)
vv[vvi++] = nums[i++];
while(j<=high)
vv[vvi++] = nums[j++];
for(i=low,vvi=0;i<=high;i++)
{
nums[i] = vv[vvi++];
}
return mid_count+left_count+right_count;
}
int InversePairs(vector<int>& nums) {
// write code here
int length = nums.size();
vv.resize(length);
return fun(nums,0,length-1)%1000000007;
}
};
因为要求时间复杂度为O(logn*n),所以简单的暴力匹配无法满足题解。
这里主要用到了归并排序的思想。
1.先将数据分为左右两个部分,然后递归求左部分的逆序数,求右部分的逆序数,最后求两个之间的逆序数。
2.主要问题出在求两个快之间的逆序数。
首先我们得明白一个知识,比如有两个快A,B。(这两个块间通过归并排序已经有序了)
A:4,6,7,8 B:2,5,9,10
我们依次从中取出元素进行排序。在A,B中第一个取的为2,那说明什么呢?
说明此时A中的所有元素都比2小,即A中的所有元素和2都可以构成一个逆序数。
因此让mid_count += mid-i+1。
然后再让其排序。
3.最后将三者的和返回即可。注意要用long int ,因为用例6的数据太大了。
#牛客创作赏金赛#牛客网刷题记录 文章被收录于专栏
本人认为值得记录的一些题
查看7道真题和解析