地址 https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/
给定一个整数数组 nums,按要求返回一个新数组 counts。 数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。 示例: 输入: [5,2,6,1] 输出: [2,1,1,0] 解释: 5 的右侧有 2 个更小的元素 (2 和 1). 2 的右侧仅有 1 个更小的元素 (1). 6 的右侧有 1 个更小的元素 (1). 1 的右侧有 0 个更小的元素.
算法1
使用归并排序解决的逆序对问题
这里尝试使用树状数组解决
由于数字取值范围没有说,可能在0到INT_MAX之间取500个值
那么使用树状数组的空间就收到了限制,不得不使用离散化.
将0到INT_MAX的取值映射到0~ 500
这里使用哈希进行离散化,然后逆序将值输入树状数组
计算每个元素的右边比他大的数字有多少个
const int maxn = 3e6; class Solution { public: int arr[maxn]; map<int, int> mp; int k = 1; int lowbit(int x) { return x & (-x); } int query(int x) { int res = 0; while (x >= 1) { res += arr[x]; x -= lowbit(x); } return res; } void update(int x) { while (x <= k) { arr[x] += 1; x += lowbit(x); } } vector<int> countSmaller(vector<int>& nums) { for (auto& e : nums) mp[e]; map<int, int>::iterator it = mp.begin(); for (; it != mp.end(); it++) { it->second = k++; } for (int i = 0; i < nums.size(); i++) { nums[i] = mp[nums[i]]; } vector<int> res; for (int i = nums.size() - 1; i >= 0; i--) { res.push_back(query(nums[i] - 1)); update(nums[i]); } reverse(res.begin(),res.end()); return res; } }; 作者:itdef 链接:https://www.acwing.com/solution/content/14614/ 来源:AcWing 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。