- Choose the invariant that makes a window valid or useful.
- Advance the right boundary and add the new element.
- Move the left boundary only as needed while maintaining the invariant and updating the answer.
Code notes
- 49 lines of C++ from the credited upstream file 3104.cpp.
- The implementation visibly relies on sequence storage.
- 4 loop blocks detected.
Complexity
Confirm that neither pointer moves backwards; if so, the scan is usually linear apart from the window’s data-structure operations.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class Solution {2 public:3 int maxSubstringLength(string s) {4 int ans = -1;5 vector<int> count(26);6 7 for (const char c : s)8 ++count[c - 'a'];9 10 for (int n = 1; n <= 26; ++n)11 ans = max(ans, maxSubstringLengthWithNUniqueLetters(s, n, count));12 13 return ans;14 }15 16 private:17 18 int maxSubstringLengthWithNUniqueLetters(const string& s, int n,19 const vector<int>& allCount) {20 int res = -1;21 22 int uniqueLetters = 0;23 24 int lettersHavingAllFreq = 0;25 vector<int> count(26);26 27 for (int l = 0, r = 0; r < s.length(); ++r) {28 if (++count[s[r] - 'a'] == 1)29 ++uniqueLetters;30 if (count[s[r] - 'a'] == allCount[s[r] - 'a'])31 ++lettersHavingAllFreq;32 while (uniqueLetters > n) {33 if (count[s[l] - 'a'] == allCount[s[l] - 'a'])34 --lettersHavingAllFreq;35 if (--count[s[l] - 'a'] == 0)36 --uniqueLetters;37 ++l;38 }39 40 41 42 if (lettersHavingAllFreq == n && r - l + 1 < s.length())43 res = max(res, r - l + 1);44 }45 46 return res;47 }48};49