题目
-
- 区间内查询数字的频率
- 区间内查询数字的频率
-
- k 镜像数字的和
思路与算法
- 第三题直接map加二分即可,见代码
- 这个第四题看了大家的题解有直接打表的,这题本意应该不是这个意思,三个基本题目的综合体,也不怎么复杂,主要逻辑即可。
代码实现
-
- 区间内查询数字的频率
class RangeFreqQuery {
public:
unordered_map<int,vector<int>> res;
public:
RangeFreqQuery(vector<int>& arr) {
for (int i = 0; i < arr.size(); ++i) {
res[arr[i]].push_back(i);
}
}
int query(int left, int right, int value) {
const vector<int> & pos = res[value];
auto l = lower_bound(pos.begin(), pos.end(), left);
auto r = upper_bound(pos.begin(), pos.end(), right);
return r - l;
}
};
/**
* Your RangeFreqQuery object will be instantiated and called as such:
* RangeFreqQuery* obj = new RangeFreqQuery(arr);
* int param_1 = obj->query(left,right,value);
*/
-
- k 镜像数字的和
using ll = long long;
class Solution {
public:
long long kMirror(int k, int n) {
vector<ll> result;
int cnt = 0;
ll st = 1;
while(cnt < n) {
ll ed = 10 * st;
for(int flag = 0; flag <= 1 && cnt < n; ++flag) {
for(ll i = st; i < ed; ++i) {
ll p = convertPalindrome(i, flag);
string kBaseNum = convertBaseNum(p, k);
if(isPalindrome(kBaseNum)) {
result.push_back(p);
if(++cnt >= n) break;
}
}
}
st *= 10;
}
ll sum = 0;
for(ll num : result) {
sum += num;
}
return sum;
}
// 回文子串检测
bool isPalindrome(const string &num){
int left = 0;
int right = num.size() - 1;
for (int i = left, j = right; i < j; ++i,--j) {
if(num[i] != num[j])
return false;
}
return true;
}
// 将十进制转化为回文数字
ll convertPalindrome(ll num, int flag) {
ll ret = num;
if(!flag)
num /= 10;
while(num) {
ret = ret * 10 + num % 10;
num /= 10;
}
return ret;
}
// 将十进制串转换为base进制的回文数字字符串
string convertBaseNum(ll num,int base){
string res;
while (num) {
res += num % base + '0';
num /= base;
}
reverse(res.begin(),res.end());
return res;
}
};
写在最后
开题开题,睡觉