Given a string
if no such substring exists, return 0.
Output: 3
Explanation: The longest substring is "aaa", as 'a' is repeated 3 times.
Output: 5
Explanation: The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.
Constraints:
1 <= s.length <= 104 s consists of only lowercase English letters.1 <= k <= 105
Contents
Solution 1 - Using sliding window technique, keep track of longest substring with at least 'k' repeating characters substring
In this approach, we will first capture the characters frequency in input string
Let's understand with an example, say the input string is
-
First, let's get the character's frequency of input string
s into a Map, this is how it looks like. -
From the above frequency count, we know for sure, longest substring cannot contain
'c' or'd' , since their count is less thank . This also means that these characters will split the input string into two parts, so the longest substring could be either left or right sides. -
Next, we iterate over each character, and when we reach letter
'c' , we know that this letter cannot be part longest substring, since it did not appeared at leastk times. Now this occurrence will break the input string into two parts, substring on the left side of letter'c' and the substring on the right side. -
Now we have to repeat the above steps on smaller input strings
s1 = "ababbb" ands2 = "add" . -
Let's construct characters frequency of
s1 ands2 . -
Let's continue with the substring
s1 and understand the intution behind the solution, from the characters frequency map ofs1 , we know that character'a' appeared only 2 times, which is less thank . So, this cannot be part of longest substring, and it will split the string into parts. There are no characters on the left side of first occurrence of character'a' so we can ignore the left side substring, and the substring on right side will bes3="babbb" . -
Next, construct the characters frequency map of
s3 = "babbb" . -
From the frequency map of
s3 , we know letter'a' cannot be part of longest substring, since it appeared only one time, so letter'a' is going to split the strings3 into two parts. Substring on left side has lesser characters thank , so we can ignore that, and the substring on right side will bes4="bbb" -
Next, construct the characters frequency map of
s4 = "bbb" . -
This is a valid substring and has each character appeared atleast
k times, so the answer is3 . -
So, what we essentially did is, we split the input string into smaller substrings based on the occurrence of letters that appeared less than
k times, and recusrively applied the solution on smaller input strings. -
Time complexity of this solution is going to be
O(n) , where n is the length of input strings , this is because we are iterating the through input string once and for each substring we capturing character frequency map, since there are 26 characters in lowercase alphabets, that will beO(26) * O(n) =>O(n) .
Implementation steps:
-
First, we will create a
helper function that takes input strings ,left starting position of current substring,right ending position of current substring, andk . -
Next, check if the current substring's length is less than
k , i.e.right -left < k , this means there are not enough characters in this substring, so we return result as0 . -
Next, create an integer array of size 26 and capture characters frequency of input string, since the input can only contain lowercase alphabets, so there can only be 26,
call it
charsFrequency . -
Next, create following 3 variables:
-
result : we will use this to store the result, we will initialize this with 0. -
start : we will use this to store the starting index for next substring, we will initialize withleft pointer to start with. -
isValid : we will use this to check if all the characters in current substring are valid or not, we will initialize this withtrue .
-
-
Next, iterate from
i = left pointer toright pointer, and do the following:-
Check if the current character at
i pointer is appeared lesser thank times, if it is, then recursively call thehelper function from fromleft pointer until where this condition occurred. We are essentially checking if the left substring has the valid longest substring or not. Also, updateisValid tofalse and update thestart pointer toi+1 inorder to skip this letter for the right side substring.
-
Check if the current character at
-
Next, check if
isValid is stilltrue , this means that the entire string is valid and is the longest substring, otherwise recursively callhelper function fromstart position to the end of stringright .
Complexity Analysis:
Time complexity: Above code runs in O(n) time, where
Space complexity: O(n), space that will be used by recursive calls stack, since there can be
Above implementations source code can be found at