Skip to content

2981. Find Longest Special Substring That Occurs Thrice I 👍

  • Time: $O(26n) = O(n)$
  • Space: $O(26n) = O(n)$
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Solution {
 public:
  int maximumLength(string s) {
    const int n = s.length();
    int ans = -1;
    int runningLen = 0;
    char prevLetter = '@';
    // counts[i][j] := the frequency of ('a' + i) repeating j times
    vector<vector<int>> counts(26, vector<int>(n + 1));

    for (const char c : s)
      if (c == prevLetter) {
        ++counts[c - 'a'][++runningLen];
      } else {
        runningLen = 1;
        ++counts[c - 'a'][runningLen];
        prevLetter = c;
      }

    for (const vector<int>& count : counts)
      ans = max(ans, getMaxFreq(count, n));

    return ans;
  }

 private:
  // Returns the maximum frequency that occurs more than three times.
  int getMaxFreq(const vector<int>& count, int maxFreq) {
    int times = 0;
    for (int freq = maxFreq; freq >= 1; --freq) {
      times += count[freq];
      if (times >= 3)
        return freq;
    }
    return -1;
  }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
  public int maximumLength(String s) {
    final int n = s.length();
    int ans = -1;
    int runningLen = 0;
    char prevLetter = '@';
    // counts[i][j] := the frequency of ('a' + i) repeating j times
    int[][] counts = new int[26][n + 1];

    for (final char c : s.toCharArray())
      if (c == prevLetter) {
        ++counts[c - 'a'][++runningLen];
      } else {
        runningLen = 1;
        ++counts[c - 'a'][runningLen];
        prevLetter = c;
      }

    for (int[] count : counts) {
      ans = Math.max(ans, getMaxFreq(count, n));
    }

    return ans;
  }

  // Returns the maximum frequency that occurs more than three times.
  private int getMaxFreq(int[] count, int maxFreq) {
    int times = 0;
    for (int freq = maxFreq; freq >= 1; --freq) {
      times += count[freq];
      if (times >= 3)
        return freq;
    }
    return -1;
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution:
  def maximumLength(self, s: str) -> int:
    n = len(s)
    runningLen = 0
    prevLetter = '@'
    # counts[i][j] := the frequency of ('a' + i) repeating j times
    counts = [[0] * (n + 1) for _ in range(26)]

    for c in s:
      if c == prevLetter:
        runningLen += 1
        counts[string.ascii_lowercase.index(c)][runningLen] += 1
      else:
        runningLen = 1
        counts[string.ascii_lowercase.index(c)][runningLen] += 1
        prevLetter = c

    def getMaxFreq(count: list[int]) -> int:
      """Returns the maximum frequency that occurs more than three times."""
      times = 0
      for freq in range(n, 0, -1):
        times += count[freq]
        if times >= 3:
          return freq
      return -1

    return max(getMaxFreq(count) for count in counts)