#include<iostream>
#include<vector>
using namespace std;
int reversePairsCore(vector<int>& nums, vector<int>& copyNums, int start, int last)
{
if(start == last)
{
copyNums[start] = nums[start];
return 0;
}
int mid = ((last-start)>>1);
int leftCount = <span style="color:#ff0000;"><strong>reversePairsCore(copyNums, nums, start, start+mid);</strong></span>
int rightCount =<span style="color:#ff0000;"><strong> reversePairsCore(copyNums, nums, start+mid+1, last);</strong></span>
int i = start+mid;
int j = last;
int count = 0;
int indexCopied = last;
while(i>=start && j>=start+mid+1)
{
if(nums[i] > nums[j])
{
count += j-start-mid;
copyNums[indexCopied--] = nums[i--];
}
else copyNums[indexCopied--] = nums[j--];
}
while(i >= start) copyNums[indexCopied--] = nums[i--];
while(j >= start+mid+1) copyNums[indexCopied--] = nums[j--];
return (leftCount + rightCount + count);
}
int reversePairs(vector<int>& nums)
{
if(nums.size() < 2) return 0;
vector<int>copyNums(nums.begin(), nums.end());
int count = reversePairsCore(nums, copyNums, 0, nums.size()-1);
for(int i=0; i<copyNums.size(); ++i) cout<<copyNums[i]<<" ";
cout<<endl;
return count;
}
int main()
{
int arr[] = {7,5,6,4};
vector<int> nums(arr, arr+sizeof(arr)/sizeof(int));
int count = reversePairs(nums);
for(int i=0; i<nums.size(); ++i) cout<<nums[i]<<" ";
cout<<endl;
cout<<count<<endl;
return 0;
}
特别需要注意的是:因为归并排序采用的是递归,因此递归的参数是关键问题。
初次编程时,没有按照红色的代码写,而是写成:
int leftCount = reversePairsCore(nums, copyNums, start, start+mid);
int rightCount = reversePairsCore(nums, copyNums, start+mid+1, last);
不是正确结果。
为什么会这样?
其实递归的过程没必要过于纠结,关键在于逻辑上行不行得通,实参设得对不对。如果逻辑上行得通,实参传错了,结果就会与正确结果不同。
注意到递归的中止条件是:start==last,然后赋值给copyNums; 我们知道排序的结果会存放在copyNums里面,自然中止条件所在的函数实参应该是copyNums赋值给nums,然后根据nums存放的值进行排序,排序结果自然就存放到copyNums,参数反转了。