目录
315. 计算右侧小于当前元素的个数
解析代码
力扣315. 计算右侧小于当前元素的个数
315. 计算右侧小于当前元素的个数
难度 困难
给你一个整数数组 nums
,按要求返回一个新数组 counts
。数组 counts
有该性质: counts[i]
的值是 nums[i]
右侧小于 nums[i]
的元素的数量。
示例 1:
输入:nums = [5,2,6,1]
输出:[2,1,1,0]
解释:
5 的右侧有 2 个更小的元素 (2 和 1)
2 的右侧仅有 1 个更小的元素 (1)
6 的右侧有 1 个更小的元素 (1)
1 的右侧有 0 个更小的元素
示例 2:
输入:nums = [-1] 输出:[0]
示例 3:
输入:nums = [-1,-1] 输出:[0,0]
提示:
1 <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4
class Solution {
public:vector<int> countSmaller(vector<int>& nums) {};
解析代码
class Solution {vector<int> ret;vector<int> index; // nums中元素的原始下标vector<int> tmp_nums;vector<int> tmp_index; // 和nums里的元素绑定一起移动
public:vector<int> countSmaller(vector<int>& nums) {int n = nums.size();ret.resize(n);index.resize(n);tmp_nums.resize(n);tmp_index.resize(n);for (int i = 0; i < n; ++i){index[i] = i;}mergeSortCnt(nums, 0, n - 1);return ret;}void mergeSortCnt(vector<int>& nums, int left, int right){if (left >= right)return;int mid = (left + right) >> 1;mergeSortCnt(nums, left, mid);mergeSortCnt(nums, mid + 1, right);int cur1 = left, cur2 = mid + 1, i = 0;while (cur1 <= mid && cur2 <= right){if (nums[cur1] > nums[cur2]){ret[index[cur1]] += (right - cur2 + 1);tmp_nums[i] = nums[cur1];tmp_index[i++] = index[cur1++];}else{tmp_nums[i] = nums[cur2];tmp_index[i++] = index[cur2++];}}while (cur1 <= mid){tmp_nums[i] = nums[cur1];tmp_index[i++] = index[cur1++];}while (cur2 <= right){tmp_nums[i] = nums[cur2];tmp_index[i++] = index[cur2++];}for (int j = left; j <= right; ++j){nums[j] = tmp_nums[j - left];index[j] = tmp_index[j - left];}}
};