一、题目描述



二、解题思路
整体思路
由于本题涉及到的是子数组 问题,所以可以采用滑动窗口+哈希表+排序来解决这个问题。维护长度为k的窗口,根据题意来计算x-sum;
具体思路
(1)首先,进行变量的声明,ret用于承接最后的返回值,hash表用于统计当前窗口内数字出现的频次;
(2)初始化第一个窗口,填写哈希表,处理第一个窗口。由于哈希表不能直接排序,所以我们需要将哈希表中的pair键值对加入到数组com中,根据题意进行排序选择,代码如下:
// 初始化第一个窗口
for(int i = 0; i < k; i++) {
hash[nums[i]]++;
}
// 处理第一个窗口
vector<pair<int,int>> consequence;
for(auto& p : hash) {
consequence.push_back(p);
}
sort(consequence.begin(), consequence.end(), compare);
long long current = 0;
int limit = min(x, (int)consequence.size());
for(int i = 0; i < limit; i++) {
current += (long long)consequence[i].first * consequence[i].second;
}
ret.push_back(current);
我们需要重写sort函数的比较器,即compare:
//重写sort比较器
static bool compare(const pair<int,int>& a, const pair<int,int>& b){
if(a.second == b.second) return a.first > b.first;
return a.second > b.second;
}
(3)利用滑动窗口来处理后面的子数组,循环中按照"进哈希表------哈希表转化成数组------排序选择------更新current------更新ret"的顺序进行处理,直到right==n;
(4)最后,返回填完的ret数组,即为所求的x-sumI;
三、代码实现
cpp
class Solution {
public:
//重写sort比较器
static bool compare(const pair<int,int>& a, const pair<int,int>& b){
if(a.second == b.second) return a.first > b.first;
return a.second > b.second;
}
vector<int> findXSum(vector<int>& nums, int k, int x) {
int n = nums.size();
vector<int> ret;
unordered_map<int, int> hash;
// 初始化第一个窗口
for(int i = 0; i < k; i++) {
hash[nums[i]]++;
}
// 处理第一个窗口
vector<pair<int,int>> consequence;
for(auto& p : hash) {
consequence.push_back(p);
}
sort(consequence.begin(), consequence.end(), compare);
long long current = 0;
int limit = min(x, (int)consequence.size());
for(int i = 0; i < limit; i++) {
current += (long long)consequence[i].first * consequence[i].second;
}
ret.push_back(current);
// 滑动窗口
for(int right = k; right < n; right++) {
int left = right - k;
// 更新哈希表
hash[nums[left]]--;
if(hash[nums[left]] == 0) {
hash.erase(nums[left]);
}
hash[nums[right]]++;
// 重建数组并排序
consequence.clear();
for(auto& p : hash) {
consequence.push_back(p);
}
sort(consequence.begin(), consequence.end(), compare);
// 计算和
current = 0;
limit = min(x, (int)consequence.size());
for(int i = 0; i < limit; i++) {
current += (long long)consequence[i].first * consequence[i].second;
}
ret.push_back(current);
}
return ret;
}
};