1、排序数组
class Solution
{
vector<int> tmp;
public:
vector<int> sortArray(vector<int>& nums)
{
tmp.resize(nums.size());
mergeSort(nums,0,nums.size() - 1);
return nums;
}
void mergeSort(vector<int>& nums, int left , int right)
{
if(left >= right) return;
int mid = (left + right) >> 1;
mergeSort(nums,left, mid);
mergeSort(nums,mid + 1, right);
int cur1 = left;
int cur2 = mid+1;
int i = 0;
while((cur1 <= mid)&&(cur2 <= right))
{
if(nums[cur1]>nums[cur2])
{
tmp[i++] = nums[cur2++];
}
else
{
tmp[i++] = nums[cur1++];
}
}
while(cur1 <= mid)
{
tmp[i++] = nums[cur1++];
}
while(cur2 <= right)
{
tmp[i++] = nums[cur2++];
}
for(int i = left; i <= right;i++)
{
nums[i] = tmp[i - left];
}
}
};
2、数组中的逆序对
(2)解题思路
方法一:暴力解法,一个一个的寻找,虽然可以找到,但是会超时
方法二:归并
我们可以先找左边部分的逆序对,再找右半部分逆序对,最后再找一左一右的,如果我们可以找的途中还能排序,会使最后一步非常的简单 变成了 左半部分 -》左排序 -》右半部分 -》右排序 -》一左一右,这和归并算法的思想差不多
class Solution
{
int tmp[50010];
public:
int reversePairs(vector<int>& nums)
{
return mergeSort(nums,0,nums.size() - 1);
}
int mergeSort(vector<int>& nums, int left, int right)
{
if(left>=right) return 0;
int ret = 0;
int mid = (left + right) >> 1;
ret += mergeSort(nums,left,mid);
ret += mergeSort(nums,mid+1,right);
int i = 0;
int cur1 = left;
int cur2 = mid + 1;
while(cur1 <= mid && cur2 <= right)
{
if(nums[cur1] <= nums[cur2])
{
tmp[i++] = nums[cur1++];
}
else
{
ret += mid - cur1 + 1;
tmp[i++] = nums[cur2++];
}
}
while(cur1<=mid)
{
tmp[i++] = nums[cur1++];
}
while(cur2<=right)
{
tmp[i++] = nums[cur2++];
}
for(int j = left; j<=right; j++)
{
nums[j] = tmp[j -left];
}
return ret;
}
};
方法一:暴力解法
方法二:和上述的算法差不多,先算左边的数,在算右边的数,再算左右两边,右侧小于当前元素的个数
class Solution
{
vector<int> tmp;
vector<int> init;
vector<int> ret;
vector<int> tmpinit;
public:
vector<int> countSmaller(vector<int>& nums)
{
tmp.resize(size(nums));
init.resize(size(nums));
ret.resize(size(nums));
tmpinit.resize(size(nums));
for(int i = 0; i<nums.size();i++)
{
init[i] = i;
}
mergeSort(nums,0,nums.size() - 1);
return ret;
}
void mergeSort(vector<int>& nums, int left , int right)
{
if(left>=right)
{
return ;
}
int mid = (left + right)>>1;
mergeSort(nums,left,mid);
mergeSort(nums, mid+1,right);
int cur1 = left;
int cur2 = mid+1;
int i =0;
while(cur1<=mid && cur2<=right)
{
if(nums[cur1]>nums[cur2])
{
ret[init[cur1]]+= right - cur2 +1;
tmp[i] = nums[cur1];
tmpinit[i++] = init[cur1++];
}
else
{
tmp[i] = nums[cur2];
tmpinit[i++] = init[cur2++];
}
}
while(cur1<=mid)
{
tmp[i] = nums[cur1];
tmpinit[i++] = init[cur1++];
}
while(cur2<=right)
{
tmp[i] = nums[cur2];
tmpinit[i++] = init[cur2++];
}
for(int i = left ; i <= right; i++)
{
nums[i] = tmp[i-left];
init[i] = tmpinit[i-left];
}
}
};
class Solution
{
vector<int> tmp;
public:
int reversePairs(vector<int>& nums)
{
tmp.resize(size(nums));
return mergeSort(nums,0,nums.size()-1);
}
int mergeSort(vector<int>& nums, int left, int right)
{
int ret = 0;
if(left>=right) return 0;
int mid = (left + right) >> 1;
ret += mergeSort(nums,left,mid);
ret += mergeSort(nums,mid+1,right);
int cur1 = left;
int cur2 = mid+1;
int i = 0;
while(cur1<=mid)
{
while(cur2<=right&&nums[cur2]>=nums[cur1]/2.0)
cur2++;
if(cur2 > right)
break;
ret += right - cur2 +1;
cur1++;
}
cur1 = left;
cur2 = mid + 1;
while(cur1 <= mid && cur2 <= right)
{
if(nums[cur1] <= nums[cur2])
{
tmp[i++] = nums[cur2++];
}
else
{
tmp[i++] = nums[cur1++];
}
}
while(cur1<=mid)
{
tmp[i++] = nums[cur1++];
}
while(cur2<=right)
{
tmp[i++] = nums[cur2++];
}
for(int j = left; j<=right; j++)
{
nums[j] = tmp[j -left];
}
return ret;
}
};