Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Think in terms of the difference between counts, not the counts separately. Let 'a' contribute and 'b' contribute .
Suppose the whole string has balance . If you remove a substring with balance , the remaining string has balance .
So the removed substring must have balance exactly . If , you can remove nothing, so the answer is .
Now the problem is: find the shortest contiguous subarray whose sum is , where every character is converted to or .
Use prefix sums. For prefix sum , a substring ending at has sum if some earlier prefix equals . To minimize length, keep the latest index where each prefix sum appeared.
Let’s strip away the story. Removing a consecutive block changes the counts only by whatever was inside that block.
Define the value of each character like this:
'a' = 'b' = For any string or substring, its sum is:
So the string has equal numbers of 'a' and 'b' exactly when its sum is .
What must be removed?
Let the total sum of the original string be .
If we remove some substring with sum , then the remaining string has sum:
We want the remaining string to be balanced, so:
Therefore:
That is the whole problem: find the shortest consecutive substring whose balance equals the total balance of the whole string.
If , the string is already balanced, so the answer is . No need to touch anything.
Prefix sums
Let be the sum of the first characters, with .
The sum of substring is:
We need:
Rearrange it:
So while scanning from left to right, suppose the current prefix sum is . We want some earlier prefix sum equal to .
If such an earlier prefix was at index , then substring has sum , and its length is:
We want the shortest length, so for each prefix sum, we should store the latest index where it appeared. Latest gives the smallest possible for the current ending position. Keeping the earliest would be great for longest subarrays, but here it would be the wrong tool. Classic off-by-one trap wearing a fake mustache.
Why output -1?
The entire string always has sum , so removing all characters always technically works. But the statement says if removing all letters is necessary, output -1.
So after finding the minimum substring length:
-1This also handles strings like aaaa or aabaa, where no proper substring can fix the imbalance.
Complexity
Each character is processed once. Prefix sums range from to , so a hash map is more than enough.
Time complexity per test case:
Memory complexity per test case:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
string s;
cin >> n >> s;
int total = 0;
for (char c : s) total += (c == 'a' ? 1 : -1);
if (total == 0) {
cout << 0 << '\n';
continue;
}
unordered_map<int, int> last;
last.reserve(2 * n + 5);
last.max_load_factor(0.7);
int ans = n;
int pref = 0;
last[0] = 0;
for (int i = 1; i <= n; i++) {
pref += (s[i - 1] == 'a' ? 1 : -1);
int need = pref - total;
auto it = last.find(need);
if (it != last.end()) {
ans = min(ans, i - it->second);
}
last[pref] = i;
}
cout << (ans == n ? -1 : ans) << '\n';
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
string s;
cin >> n >> s;
int total = 0;
for (char c : s) total += (c == 'a' ? 1 : -1);
if (total == 0) {
cout << 0 << '\n';
continue;
}
unordered_map<int, int> last;
last.reserve(2 * n + 5);
last.max_load_factor(0.7);
int ans = n;
int pref = 0;
last[0] = 0;
for (int i = 1; i <= n; i++) {
pref += (s[i - 1] == 'a' ? 1 : -1);
int need = pref - total;
auto it = last.find(need);
if (it != last.end()) {
ans = min(ans, i - it->second);
}
last[pref] = i;
}
cout << (ans == n ? -1 : ans) << '\n';
}
return 0;
}