题目
描述
给定一个整数数组 (下标由 0 到 n-1,其中 n 表示数组的规模,数值范围由 0 到 10000),以及一个 查询列表。对于每一个查询,将会给你一个整数,请你返回该数组中小于给定整数的元素的数量。
样例
样例 1:
输入: array =[1,2,7,8,5] queries =[1,8,5]
输出:[0,4,2]
样例 2:
输入: array =[3,4,5,8] queries =[2,4]
输出:[0,1]
分析
给定数组中数值最大为10000,那我们可以用哈希表统计每个数值的数量,我们想如果需要比较的数字大于10000,那它就比给定数组中所有数字都大,这里我们就可以用坐标型动态规划
坐标型动态规划,哈希表统计给定数组各个数值的个数,状态f[i] i代表当前要计算的数字 f[i]的值代表比i小的数字的个数 转移方程 f[i]=f[i-1]+hash[i-1] 比如我们计算比10小的数字的个数 只需要知道比9小的个数加上9的个数
题中给定数组最大值10000 所以f[i]当i>10000 它的值一定是f[10001] 也可以理解为比给定数组中所有值都大
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
vector<int> countOfSmallerNumber(vector<int> &a, vector<int> &queries) {
vector<int> hash_map(10001,0); //各个数值的个数
for(int i=0;i<a.size();i++)
{
hash_map[a[i]]+=1;
}
vector<int> f(10002,0); //状态 代表比当前数值小的数值的个数
for(int i=1;i<10002;i++)
f[i]=f[i-1]+hash_map[i-1]; //上一个状态+上一个数值的数量
vector<int> ans;
for(int i=0;i<queries.size();i++)
{
int val=queries[i];
if(val>10001)
{
ans.push_back(f[10001]);
continue;
}
ans.push_back(f[val]);
}
return ans;
}
};
int main (void)
{
vector<int> a={1,2,7,8,5};
vector<int> q={1,8,5};
vector<int> ans;
Solution s;
ans=s.countOfSmallerNumber(a,q);
for(int i=0;i<ans.size();i++)
cout<<ans[i]<<" ";
return 0;
}
总结
本来是一道练习线段树的题,突发奇想用了坐标型动态规划,发现这种方法对于这道题来说效率是最高的