给你一个整数数组 nums ,按要求返回一个新数组 counts 。数组 counts 有该性质: counts[i] 的值是nums[i] 右侧小于 nums[i] 的元素的数量。
class Solution {
vector<int> index; //记录序号
vector<int> temp; //临时的数组
vector<int> tempIndex; //临时数组对应的序号
vector<int> ans; //答案
public:
void merge(vector<int> & nums, int left, int mid, int right){
int fir = left, sec = mid + 1, sorted = left;//不能出现写sorted = 1这种错误,这都是对数组的相对位置进行操作的
while(fir <= mid && sec <= right){
//如果第一个序列的小,那么加入到临时数组的sorted位置
//并且把相应序号加入临时序号数组
if(nums[fir] <= nums[sec]){
temp[sorted] = nums[fir];
tempIndex[sorted] = index[fir];
//更新贡献值
ans[index[fir]] += (sec - mid - 1);
++fir;
++sorted;
}
//同理第二个序列小,就拿第二个序列的出来加入
else{
temp[sorted] = nums[sec];
tempIndex[sorted] = index[sec];
++sec;
++sorted;
}
}
//如果第二个序列加入完了,就直接把第一个序列剩下没加入的一起加入到末尾
while(fir <= mid){
temp[sorted] = nums[fir];
tempIndex[sorted] = index[fir];
ans[index[fir]] += (sec - mid - 1);
++fir;
++sorted;
}
//如果第一个序列加入完了,就直接把第二个序列剩下没加入的一起加入到末尾
while(sec <= right){
temp[sorted] = nums[sec];
tempIndex[sorted] = index[sec];
++sec;
++sorted;
}
//更新原序号与原数组
//最初为什么不直接更新,是因为会影响到数组的顺序,导致数据混乱
for(int i = left; i <= right; ++i){
index[i] = tempIndex[i];
nums[i] = temp[i];
}
}
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);
merge(nums,left, mid, right);
}
vector<int> countSmaller(vector<int>& nums) {
int n = nums.size();
index.resize(n);
temp.resize(n);
tempIndex.resize(n);
ans.resize(n);
//构造序号数组
for(int i = 0; i < n; ++i)
index[i] = i;
mergeSort(nums, 0, n - 1);
return ans;
}
};
Accepted
65/65 cases passed (316 ms)
Your runtime beats 40.23 % of cpp submissions
Your memory usage beats 56.35 % of cpp submissions (77.2 MB)