题目如下
数据范围
示例
这题十分有意思一开始我想对每个子数组排序二分结果超时了。
转换思路:我们可以提前把每个数字出现的位置先记录下来形成集合,
然后拿着left和right利用二分查找看看left和right是不是在集合里然后做一个相减就出答案了。
通过代码
cpp
class RangeFreqQuery {
public:
unordered_map<int,vector<int>> map;
//unordered_map<string,int> mapc;
RangeFreqQuery(vector<int>& arr) {
int n = arr.size();
for(int i = 0;i < n;i++){
if(map.count(arr[i]) == 1)map[arr[i]].emplace_back(i);
else{
map[arr[i]] = vector<int>{i};
}
}
}
int findlow(vector<int>& nums,int target) {
int n = nums.size();
int l = 0, r = n - 1;
int mid;
while (l < r) {
mid = (l + r) / 2;
if (nums[mid] >= target) {
r = mid;
} else{
l = mid + 1;
}
}
if(nums[l] < target)return -1;
return l;
}
int findhigh(vector<int>& nums,int target) {
int n = nums.size();
int l = 0, r = n - 1;
int mid;
while (l < r) {
mid = (l + r + 1) / 2;
if (nums[mid] > target) {
r = mid - 1;
} else{
l = mid;
}
}
if(nums[l] > target)return -1;
return l;
}
int query(int left, int right, int value) {
// string a = to_string(left) + "+" + to_string(right) + "+" + to_string(value);
// if(mapc.count(a) == 1)return mapc[a];
if(map.count(value) == 0)return 0;
vector<int>& v = map[value];
int l = findlow(v,left);
int r = findhigh(v,right);
if(l != -1 && r != -1){
// mapc[a] = r - l + 1;
return r - l + 1;
}
return 0;
}
};
/**
* Your RangeFreqQuery object will be instantiated and called as such:
* RangeFreqQuery* obj = new RangeFreqQuery(arr);
* int param_1 = obj->query(left,right,value);
*/