leetcode.1365 有多少小于当前数字的数字
题干
给你一个数组 nums,对于其中每个元素 nums[i],请你统计数组中比它小的所有数字的数目。
换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j != i 且 nums[j] < nums[i] 。
以数组形式返回答案。
示例 1:
输入:nums = [8,1,2,2,3]
输出:[4,0,1,1,3]
示例 2:
输入:nums = [6,5,4,8]
输出:[2,1,0,3]
示例 3:
输入:nums = [7,7,7,7]
输出:[0,0,0,0]
提示:
2 <= nums.length <= 500
0 <= nums[i] <= 100
题解
丑陋暴力法
class Solution {
public:
vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
int n = nums.size();
vector<int> ans(n,0);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(nums[j]<nums[i]){
ans[i]++;
}
}
}
return ans;
}
};
很容易想到的排序数组记录数字在原数组的位置
class Solution {
public:
vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
int n = nums.size();
vector<pair<int,int> > orderedNums;
for(int i=0;i<n;i++){
orderedNums.push_back({nums[i],i});
}
sort(orderedNums.begin(),orderedNums.end());
vector<int> ans(n);
ans[orderedNums[0].second] = 0;
int sameSmallerCount = 0;
for(int i=1;i<n;i++){
if(orderedNums[i].first>orderedNums[i-1].first){
ans[orderedNums[i].second] = i;
sameSmallerCount = i;
}
else{
ans[orderedNums[i].second] = sameSmallerCount;
}
}
return ans;
}
};
空间换时间
* 遍历找出最大数,开辟对应下标数组count(映射思想)
* 遍历数组,对于数字nums[i]将其出现次数统计在数组count[nums[i]]中
* 对于nums[i]来说,小于他的数的个数即为count[0-(i-1)]的和,累计加和处理后,访问nums[i]-1下标即可
* 注意最后询问时若nums[i]==0则访问0,否则会出现下标越界的错误
class Solution {
public:
vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
int n = nums.size();
int maxNum = INT_MIN;
for(int i=0;i<n;i++){
maxNum = max(maxNum,nums[i]);
}
vector<int> count(maxNum+5,0);
for(int i=0;i<n;i++){
count[nums[i]]++;
}
for(int i=1;i<=maxNum;i++){
count[i] = count[i-1] + count[i];
}
for(int i=0;i<n;i++){
nums[i] = nums[i]==0 ? 0 : count[nums[i]-1];
}
return nums;
}
};