
分治的两大排序算法,一个是快速排序,另一个则是归并排序。形象地说,在处理数据的顺序方面,快速排序是先序遍历,而归并排序是后序遍历。

思路:
class Solution
{
vector<int> tmp;
public:
void mergeSort(vector<int>& nums, int begin, int end)
{
if(begin == end) return;
int mid = begin + (end - begin) / 2;
mergeSort(nums, begin, mid);
mergeSort(nums, mid + 1, end);
int begin1 = begin, end1 = mid, begin2 = mid + 1, end2 = end, k = begin;
while(begin1 <= end1 && begin2 <= end2)
{
if(nums[begin1] < nums[begin2]) tmp[k++] = nums[begin1++];
else tmp[k++] = nums[begin2++];
}
while(begin1 <= end1) tmp[k++] = nums[begin1++];
while(begin2 <= end2) tmp[k++] = nums[begin2++];
for(int i=begin; i<=end; i++) nums[i] = tmp[i];
}
vector<int> sortArray(vector<int>& nums)
{
tmp.resize(nums.size());
mergeSort(nums, 0, nums.size() - 1);
return nums;
}
};

思路:
升序版本:
class Solution
{
int ret;
vector<int> tmp;
public:
void mergeSort(vector<int>& nums, int begin, int end)
{
if(begin >= end) return;
int mid = begin + (end - begin) / 2;
mergeSort(nums, begin, mid);
mergeSort(nums, mid + 1, end);
int cur1 = begin, cur2 = mid + 1, k = begin;
while(cur1 <= mid && cur2 <= end)
{
if(nums[cur1] <= nums[cur2]) tmp[k++] = nums[cur1++];
else
{
tmp[k++] = nums[cur2++];
ret += mid + 1 - cur1;
}
}
while(cur1 <= mid) tmp[k++] = nums[cur1++];
while(cur2 <= end) tmp[k++] = nums[cur2++];
for(int i=begin; i<=end; i++) nums[i] = tmp[i];
}
int reversePairs(vector<int>& nums)
{
tmp.resize(nums.size());
mergeSort(nums, 0, nums.size() - 1);
return ret;
}
};

思路:
class Solution
{
vector<int> ret;
int tmp[100005];
int index[100005];
int tmpi[100005];
public:
void mergeSort(vector<int>& nums, int begin, int end)
{
if(begin >= end) return;
int mid = begin + (end - begin) / 2;
mergeSort(nums, begin, mid);
mergeSort(nums, mid + 1, end);
int cur1 = begin, cur2 = mid + 1, k = begin;
while(cur1 <= mid && cur2 <= end)
{
if(nums[cur1] <= nums[cur2])
{
tmpi[k] = index[cur2];
tmp[k++] = nums[cur2++];
}
else
{
ret[index[cur1]] += end + 1 - cur2;
tmpi[k] = index[cur1];
tmp[k++] = nums[cur1++];
}
}
while(cur1 <= mid)
{
tmpi[k] = index[cur1];
tmp[k++] = nums[cur1++];
}
while(cur2 <= end)
{
tmpi[k] = index[cur2];
tmp[k++] = nums[cur2++];
}
for(int i=begin; i<=end; i++)
{
nums[i] = tmp[i];
index[i] = tmpi[i];
}
}
vector<int> countSmaller(vector<int>& nums)
{
int n = nums.size();
ret.resize(n);
for(int i=0; i<n; i++) index[i] = i;
mergeSort(nums, 0, n - 1);
return ret;
}
};

思路:
class Solution
{
int ret;
int tmp[50005];
public:
void mergeSort(vector<int>& nums, int begin, int end)
{
if(begin >= end) return;
int mid = begin + (end - begin) / 2;
mergeSort(nums, begin, mid);
mergeSort(nums, mid + 1, end);
int left = begin, right = mid + 1;
while(left <= mid && right <= end)
{
//因为分类条件与归并不同,所以要分开写
if(nums[left] <= 2 * (long long)nums[right]) left++;//强转long long,防止溢出
else
{
ret += mid + 1 - left;
right++;
}
}
int cur1 = begin, cur2 = mid + 1, k = begin;
while(cur1 <= mid && cur2 <= end)
{
if(nums[cur1] <= nums[cur2]) tmp[k++] = nums[cur1++];
else tmp[k++] = nums[cur2++];
}
while(cur1 <= mid) tmp[k++] = nums[cur1++];
while(cur2 <= end) tmp[k++] = nums[cur2++];
for(int i=begin; i<=end; i++) nums[i] = tmp[i];
}
int reversePairs(vector<int>& nums)
{
mergeSort(nums, 0, nums.size() - 1);
return ret;
}
};
