Opening the reading…
Opening the reading…
SLIDING WINDOW › FIXED SIZE SLIDING-WINDOW
Open — the attempt gate is not wired up yet
This editorial is meant to unlock after you have run the problem at least once, with the worked solution behind one further deliberate click. That needs per-learner unlock state nothing stores today, so for now the whole article is open.
Try it yourself first →Every candidate has exactly k consecutive elements, so adjacent candidates differ in only two positions: one new value enters on the right and one old value leaves on the left. Recomputing each sum and rebuilding distinctness from scratch would repeat nearly all the work. Instead, keep the current window's sum and update it with those two changes.
A window is valid precisely when every value appears once. A frequency map records how many times each value occurs, while its number of keys tells you how many distinct values are present. Once the window has length k, frequency-map size k means all k positions hold different values, so its maintained sum is a candidate for the maximum.
| MEASURE | BOUND | WHY |
|---|---|---|
| Time | Expected O(n); worst-case O(n^2) | Each array value is inserted once and, after it moves k positions behind the scan, removed once. Hash-map updates and lookups are expected O(1), so the total expected work is linear; adversarial collisions can make individual updates slower. |
| Space | O(k) extra, worst case O(n) | The map contains only values in the current window, so it has at most k entries; when k equals n, that is O(n). The returned value is a required scalar output and is not working memory. |
#include <algorithm>
#include <unordered_map>
#include <vector>
using namespace std;
class Solution {
public:
long long maximumSubarraySum(vector<int>& nums, int k) {
unordered_map<int, int> freq;
long long sum = 0;
long long maxSum = 0;
int n = nums.size();
for (int i = 0; i < n; ++i) {
++freq[nums[i]];
sum += nums[i];
if (i >= k) {
int outgoing = nums[i - k];
if (--freq[outgoing] == 0) {
freq.erase(outgoing);
}
sum -= outgoing;
}
if (i >= k - 1 && static_cast<int>(freq.size()) == k) {
maxSum = max(maxSum, sum);
}
}
return maxSum;
}
};The order of the update is important. The incoming value is added first, then the value k positions behind the new right endpoint is removed. Only after both operations does the map describe the current length-k window. The guard i >= k - 1 prevents shorter prefixes from being considered, while the long long sum prevents a valid window's total from overflowing int.
Because every nums[i] lies between 1 and 100000, you can replace the hash map with a frequency vector indexed by value. This is an optimization, not a different sliding-window idea: it removes hashing overhead and gives worst-case linear time. It uses O(100000) extra memory regardless of k, so the map version is preferable when the value range is not known or is much larger.
#include <algorithm>
#include <vector>
using namespace std;
class Solution {
public:
long long maximumSubarraySum(vector<int>& nums, int k) {
vector<int> freq(100001, 0);
long long sum = 0;
long long maxSum = 0;
int distinct = 0;
for (int i = 0; i < static_cast<int>(nums.size()); ++i) {
if (freq[nums[i]] == 0) {
++distinct;
}
++freq[nums[i]];
sum += nums[i];
if (i >= k) {
int outgoing = nums[i - k];
--freq[outgoing];
if (freq[outgoing] == 0) {
--distinct;
}
sum -= outgoing;
}
if (i >= k - 1 && distinct == k) {
maxSum = max(maxSum, sum);
}
}
return maxSum;
}
};The distinct counter replaces freq.size(). Increment it when a value's frequency changes from zero to one, and decrement it when the outgoing value's frequency changes from one to zero. The counter must describe values currently in the window, so both transitions happen alongside insertion and removal rather than when the value is first seen globally.