classSolution: defmaximumLength(self, s: str) -> int: n = len(s) # groups = [Counter() for _ in range(26)] # TLE groups = [[0] * (n+1) for _ inrange(26)] # AC i = 0 while i < n: # 分組循環 st, i, idx = i, i+1, ord(s[i]) - ord("a") while (i < n and s[i] == s[st]): i += 1 # for k in range(1, i - st + 1): # 長度為 k 的子字串有 i - st - k + 1 個 for k inrange(i - st, max(0, i - st - 3), -1): # 其實最多考慮 3 個就夠了 groups[idx][k] += i - st - k + 1 ans = -1 for g in groups: # for i in range(n, 0, -1): for i inrange(n-2, 0, -1): # 需要出現至少 3 次 if g[i] >= 3: # 滿足條件 ans = max(ans, i) break return ans
classSolution { public: intmaximumLength(string s){ int n = s.size(), i = 0; vector<vector<int>> groups(26, vector<int>(n+1, 0)); while (i < n){ // 分組循環 int st = i++; while (i < n && s[i] == s[st]) i++; // for (int k = 1; k <= i - st; k++) // 長度為 k 的子字串有 i - st - k + 1 個 for (int k = i - st; k >= max(1, i - st - 2); k--) // 其實最多考慮 3 個就夠了 groups[s[st] - 'a'][k] += (i - st) - k + 1; } int ans = -1; for (auto g : groups) // for (int i = n; i > 0; i--) for (int i = n-2; i > 0; i--) // 需要出現至少 3 次 if (g[i] >= 3){ // 滿足條件 ans = max(ans, i); break; } return ans; } };
classSolution: defmaximumLength(self, s: str) -> int: n = len(s) groups = [[] for _ inrange(26)] i = 0 while i < n: # 分組循環 st, i = i, i+1 while (i < n and s[i] == s[st]): i += 1 groups[ord(s[st]) - ord("a")].append(i - st) ans = 0 for g in groups: m = len(g) if m == 0: continue g.sort(reverse=True) ans = max(ans, g[0]-2) if m > 1: ans = max(ans, min(g[0]-1, g[1])) if m > 2: ans = max(ans, g[2]) return ans if ans > 0else -1
classSolution { public: intmaximumLength(string s){ int n = s.size(), i = 0; vector<vector<int>> groups(26, vector<int>()); while (i < n){ int st = i++; while (i < n && s[i] == s[st]) i++; groups[s[st] - 'a'].push_back(i - st); } int ans = 0; for (auto g : groups){ int m = g.size(); if (m == 0) continue; sort(g.begin(), g.end(), greater<int>()); ans = max(ans, g[0] - 2); if (m > 1) ans = max(ans, min(g[0] - 1, g[1])); if (m > 2) ans = max(ans, g[2]); } return ans > 0 ? ans : -1; } };
方法三:分組循環 + 分類討論 + 堆積(Heap)
如同方法二的思路,但既然我們只需要考慮前 3 大的值,那不妨使用 堆積(Heap) 來維護每組的前 3 大的值。在每一段的長度加入到該字母的分組 gi 中後,若長度超過 3 個,則將最小的長度移除。在 Python 中可以使用 heapq 模組中的 heappush 和 heappop 來維護 Min Heap,而在 C++ 中可以使用 priority_queue 來維護 Min Heap。
classSolution: defmaximumLength(self, s: str) -> int: n = len(s) groups = [[] for _ inrange(26)] i = 0 while i < n: # 分組循環 st = i while (i < n and s[i] == s[st]): i += 1 idx = ord(s[st]) - ord("a") iflen(groups[idx]) >= 3: heappushpop(groups[idx], (i - st)) # Min heap else: heappush(groups[idx], (i - st)) # Min heap ans = 0 for g in groups: m = len(g) if m == 0: continue tmp = [0] * 3 for i inrange(m-1, -1, -1): tmp[i] = heappop(g) ans = max(ans, tmp[0]-2, min(tmp[0]-1, tmp[1]), tmp[2]) return ans if ans > 0else -1
classSolution { public: intmaximumLength(string s){ int n = s.size(), i = 0; priority_queue<int, vector<int>, greater<int>> groups[26]; // Min heap while (i < n){ int st = i++; while (i < n && s[i] == s[st]) i++; groups[s[st] - 'a'].push(i - st); if (groups[s[st] - 'a'].size() > 3) groups[s[st] - 'a'].pop(); } int ans = 0; for (auto g : groups){ int m = g.size(); if (m == 0) continue; vector<int> tmp(3, 0); for (int i = m-1; i >= 0; i--) tmp[i] = g.top(), g.pop(); ans = max({ans, tmp[0] - 2, min(tmp[0] - 1, tmp[1]), tmp[2]}); } return ans > 0 ? ans : -1; } };
寫在最後
Cover photo is generated by @ゴリラの素材屋さん, thanks for their work!