{x}
blog image

Maximum Number of Occurrences of a Substring

Given a string s, return the maximum number of occurrences of any substring under the following rules:

  • The number of unique characters in the substring must be less than or equal to maxLetters.
  • The substring size must be between minSize and maxSize inclusive.

 

Example 1:

Input: s = "aababcaab", maxLetters = 2, minSize = 3, maxSize = 4
Output: 2
Explanation: Substring "aab" has 2 occurrences in the original string.
It satisfies the conditions, 2 unique letters and size 3 (between minSize and maxSize).

Example 2:

Input: s = "aaaa", maxLetters = 1, minSize = 3, maxSize = 3
Output: 2
Explanation: Substring "aaa" occur 2 times in the string. It can overlap.

 

Constraints:

  • 1 <= s.length <= 105
  • 1 <= maxLetters <= 26
  • 1 <= minSize <= maxSize <= min(26, s.length)
  • s consists of only lowercase English letters.

Solution Explanation for 1297. Maximum Number of Occurrences of a Substring

This problem asks to find the maximum number of occurrences of any substring within a given string s, subject to constraints on the number of unique characters and the substring length.

Approach:

The optimal approach involves using a sliding window of size minSize and a hash table (or dictionary) to efficiently count substring occurrences. Since any substring that meets the criteria will have a substring of length minSize also meeting the criteria, we only need to consider substrings of length minSize.

  1. Sliding Window: We iterate through the string s using a sliding window of size minSize. For each window, we extract the substring.

  2. Unique Character Check: We check if the number of unique characters in the substring is less than or equal to maxLetters. We use a Set (or equivalent data structure) for efficient unique character counting.

  3. Frequency Counting: If the substring satisfies the unique character constraint, we increment its count in the hash table (cnt). We maintain a variable ans to track the maximum frequency encountered so far.

  4. Result: After iterating through all substrings of size minSize, ans holds the maximum number of occurrences of any substring meeting the given criteria.

Time Complexity Analysis:

  • The outer loop iterates len(s) - minSize + 1 times.
  • Inside the loop, checking the number of unique characters takes O(minSize) time in the worst case.
  • Hash table operations (insertion and lookup) take O(1) on average.
  • Therefore, the overall time complexity is O(len(s) * minSize). Since minSize is constrained to be at most 26, we can consider the time complexity approximately O(len(s)).

Space Complexity Analysis:

  • The hash table (cnt) stores substrings of length minSize. In the worst case, the number of unique substrings could be O(len(s)).
  • The Set used for unique character counting has a maximum size of 26 (number of lowercase English letters).
  • Therefore, the space complexity is O(len(s)).

Code Examples:

The provided code examples in Python, Java, C++, Go, and TypeScript all implement this approach. They differ slightly in syntax but follow the same algorithmic structure. Key aspects are:

  • The use of a Counter (Python), HashMap (Java), unordered_map (C++), map (Go), and Map (TypeScript) to efficiently store substring counts.
  • The use of a Set (Python, Java, C++, TypeScript) and map (Go) to efficiently count unique characters.

The code snippets below are representative of the provided code (variations exist due to language differences in syntax). Remember that the exact implementation details might differ slightly depending on the specific language used.

Python (Illustrative):

from collections import Counter
 
def maxFreq(s: str, maxLetters: int, minSize: int, maxSize: int) -> int:
    ans = 0
    cnt = Counter()
    for i in range(len(s) - minSize + 1):
        substring = s[i:i + minSize]
        unique_chars = set(substring)
        if len(unique_chars) <= maxLetters:
            cnt[substring] += 1
            ans = max(ans, cnt[substring])
    return ans

The other language examples follow a very similar pattern, adjusting only for the specific language features. The core logic of the sliding window, unique character check, and frequency counting remains identical across all solutions.