<p>You are given a string <code>s</code> that consists of lowercase English letters.</p>

<p>A string is called <strong>special</strong> if it is made up of only a single character. For example, the string <code>&quot;abc&quot;</code> is not special, whereas the strings <code>&quot;ddd&quot;</code>, <code>&quot;zz&quot;</code>, and <code>&quot;f&quot;</code> are special.</p>

<p>Return <em>the length of the <strong>longest special substring</strong> of </em><code>s</code> <em>which occurs <strong>at least thrice</strong></em>, <em>or </em><code>-1</code><em> if no special substring occurs at least thrice</em>.</p>

<p>A <strong>substring</strong> is a contiguous <strong>non-empty</strong> sequence of characters within a string.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;aaaa&quot;
<strong>Output:</strong> 2
<strong>Explanation:</strong> The longest special substring which occurs thrice is &quot;aa&quot;: substrings &quot;<u><strong>aa</strong></u>aa&quot;, &quot;a<u><strong>aa</strong></u>a&quot;, and &quot;aa<u><strong>aa</strong></u>&quot;.
It can be shown that the maximum length achievable is 2.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;abcdef&quot;
<strong>Output:</strong> -1
<strong>Explanation:</strong> There exists no special substring which occurs at least thrice. Hence return -1.
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;abcaba&quot;
<strong>Output:</strong> 1
<strong>Explanation:</strong> The longest special substring which occurs thrice is &quot;a&quot;: substrings &quot;<u><strong>a</strong></u>bcaba&quot;, &quot;abc<u><strong>a</strong></u>ba&quot;, and &quot;abcab<u><strong>a</strong></u>&quot;.
It can be shown that the maximum length achievable is 1.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>3 &lt;= s.length &lt;= 50</code></li>
	<li><code>s</code> consists of only lowercase English letters.</li>
</ul>

class Solution:
    def maximumLength(self, s: str) -> int:
        # Count every longest special substring for each character
        # O(n) time and space
        # char_strcnt = [[0 for j in range(len(s))] for i in range(26)]
        # curr_char = None
        # curr_cnt = 0

        # for c in s:
        #     if curr_char is None:
        #         curr_char = c
        #         curr_cnt = 1
        #         continue

        #     if curr_char == c:
        #         curr_cnt += 1
        #     else:
        #         idx = ord(curr_char) - ord('a')
        #         char_strcnt[idx][curr_cnt - 1] += 1
        #         curr_char = c
        #         curr_cnt = 1
        # idx = ord(curr_char) - ord('a')
        # char_strcnt[idx][curr_cnt - 1] += 1

        # max_len = -1
        # for i in range(26):
        #     curr_strcnt = char_strcnt[i]
        #     # If 'aaaa' appears, 'aa' must appear twice
        #     for j in range(len(s) - 1, -1, -1):
        #         strcnt = curr_strcnt[j]
        #         if strcnt >= 3:
        #             max_len = max(max_len, j + 1)
        #         elif strcnt == 2:
        #             max_len = max(max_len, j)
        #         elif strcnt == 1:
        #             if j != 0:
        #                 if curr_strcnt[j - 1] > 0:
        #                     max_len = max(max_len, j)
        #                 else:
        #                     max_len = max(max_len, j - 1)

        # if max_len == 0:  # Edge case
        #     return -1
        # return max_len



        # O(1) space
        # For each character, only keep 3 longest special substrings
        char_top3 = collections.defaultdict(list)
        curr_char = None
        curr_cnt = 0

        for c in s:
            if curr_char is None:
                curr_char = c
                curr_cnt = 1
            elif curr_char == c:
                curr_cnt += 1
            else:
                char_top3[curr_char].append(curr_cnt)
                if len(char_top3[curr_char]) > 3:
                    char_top3[curr_char].remove(min(char_top3[curr_char]))
                curr_char = c
                curr_cnt = 1
     
        char_top3[curr_char].append(curr_cnt)
        if len(char_top3[curr_char]) > 3:
            char_top3[curr_char].remove(min(char_top3[curr_char]))

        max_len = -1
        for c in char_top3:
            top3 = sorted(char_top3[c])
            if len(top3) == 0:
                continue

            if len(top3) == 1:
                max_len = max(max_len, top3[0] - 2)

            elif len(top3) == 2:
                mid_len, top_len = top3
                if mid_len == top_len:
                    max_len = max(max_len, top_len - 1)
                else:
                    max_len = max(max_len, max(top_len - 2, mid_len))

            else:
                short_len, mid_len, top_len = top3
                if short_len == mid_len and mid_len == top_len:
                    max_len = max(max_len, top_len)
                elif mid_len == top_len:
                    max_len = max(max_len, top_len - 1)
                else:
                    max_len = max(max_len, max(top_len - 2, mid_len))

        return -1 if max_len == 0 else max_len


32