Problem
Given a string s
and an integer k
, return the length of the longest substring of s
such that the frequency of each character in this substring is greater than or equal to k
.
if no such substring exists, return 0.
Examples
Example 1:
Input:
s = "aaabb", k = 3
Output:
3
Explanation: The longest substring is "aaa", as 'a' is repeated 3 times.
Example 2:
Input:
s = "ababbc", k = 2
Output:
5
Explanation: The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.
Solution
Method 1 - Recursion
To solve the problem of finding the length of the longest substring in s
such that the frequency of each character in this substring is greater than or equal to k
, the idea is to use a divide-and-conquer strategy.
Here are the steps:
- Frequency Calculation:
- Calculate the frequency of each character in the string.
- Divide and Conquer:
- If a character’s frequency is less than
k
, then this character cannot be part of the valid substring. This splits the problem into smaller substrings. - Recursively check each of these substrings to find the longest valid substring.
- If a character’s frequency is less than
- Base Case:
- If every character in the string meets the frequency requirement, return the length of the string.
Pseudo code
- Define a recursive function that finds the longest valid substring.
- Compute character frequencies for the given substring.
- Identify split points where a character’s frequency is less than
k
. - Recurse into substrings formed by splitting at these points.
- Return the maximum length found in these substrings.
Code
Java
public class Solution {
public int longestSubstring(String s, int k) {
return longestSubstringHelper(s, 0, s.length(), k);
}
private int longestSubstringHelper(String s, int start, int end, int k) {
if (end - start < k) return 0; // Base case: not enough length to meet k requirement
int[] freq = new int[26];
for (int i = start; i < end; i++) {
freq[s.charAt(i) - 'a']++;
}
for (int i = start; i < end; i++) {
if (freq[s.charAt(i) - 'a'] < k) {
int j = i + 1;
while (j < end && freq[s.charAt(j) - 'a'] < k) j++;
return Math.max(longestSubstringHelper(s, start, i, k), longestSubstringHelper(s, j, end, k));
}
}
return end - start; // All characters in this range meet the k requirement
}
}
Python
class Solution:
def longestSubstring(self, s: str, k: int) -> int:
return self._longestSubstring(s, 0, len(s), k)
def _longestSubstring(self, s: str, start: int, end: int, k: int) -> int:
if end - start < k:
return 0 # Base case: not enough length to meet k requirement
freq = [0] * 26
for i in range(start, end):
freq[ord(s[i]) - ord('a')] += 1
for i in range(start, end):
if freq[ord(s[i]) - ord('a')] < k:
j = i + 1
while j < end and freq[ord(s[j]) - ord('a')] < k:
j += 1
return max(self._longestSubstring(s, start, i, k), self._longestSubstring(s, j, end, k))
return end - start # All characters in this range meet the k requirement
Complexity
- Time:
O(n*n)
, which isO(n^2)
because each recursive call processes a substring and can make further recursive calls proportional to the length of the substring. - Space:
O(n)
, due to the recursion stack.