Leetcode 1100. Find K-Length Substrings With No Repeated Characters
Table of Contents
Problem Informations
- Problem Index: 1100
- Problem Link: Find K-Length Substrings With No Repeated Characters
- Topics: Hash Table, String, Sliding Window
Problem Description
Given a string $s$ and an integer $k$, return the number of substrings in $s$ of length $k$ with no repeated characters.
Example 1:
Input: $s = “havefunonleetcode”$, $k = 5$
Output: 6
Explanation: There are 6 substrings they are: ‘havef’, ‘avefu’, ‘vefun’, ’efuno’, ’etcod’, ’tcode’.
Example 2:
Input: $s = “home”$, $k = 5$
Output: 0
Explanation: Notice $k$ can be larger than the length of $s$. In this case, it is not possible to find any substring.
Constraints:
- $1 \leq s.\text{length} \leq 10^4$
- $s$ consists of lowercase English letters.
- $1 \leq k \leq 10^4$
Intuition
The task is to determine the number of substrings of length $k$ in a given string $s$ that contain no repeated characters. This requires efficient handling of substrings to ensure uniqueness of characters. Using a sliding window approach allows us to efficiently manage and update the window as we progress through the string. The sliding window technique leverages the properties of continuous segments in an array or string, making it optimal for this situation where overlap and progression are key.
Approach
The algorithm employs a sliding window paradigm using two pointers to define the start (left
) and the end (right
) of the current window, which represents a substring of $s$. Here are the steps involved:
Initialization:
- Use a boolean vector
is_char_used
of size 26 (the total number of lowercase English letters) initialized tofalse
to track the usage of each character within the current substring. - Initialize
left
,right
, andresult_count
to zero.left
andright
pointers manage the sliding window’s boundaries, whileresult_count
tracks the number of valid substrings found.
- Use a boolean vector
Window Expansion:
- Traverse the string using the
right
pointer while it is less than the length of the string. On each iteration, check if the character ats[right]
has already been used in the current window.
- Traverse the string using the
Character Repetition Handling:
- If the character at
s[right]
is already marked as used, increment theleft
pointer to shrink the window from the left until the character is unique. During this process, mark the characters ats[left]
as not used inis_char_used
.
- If the character at
Character Usage Marking:
- Mark the character at
s[right]
as used by setting the corresponding index inis_char_used
totrue
.
- Mark the character at
Window Size Validation:
- Check if the window size $(\text{right} - \text{left} + 1)$ is at least $k$. If so, it indicates a valid substring, and
result_count
is incremented.
- Check if the window size $(\text{right} - \text{left} + 1)$ is at least $k$. If so, it indicates a valid substring, and
Result Return:
- Once the loop ends, the
result_count
holding the number of valid substrings found is returned.
- Once the loop ends, the
This process ensures that each character is only ever considered once within any potential $k$-length substring, satisfying the requirement of non-repetition efficiently through the use of a sliding window and tracking mechanism.
Code
C++
class Solution {
public:
int numKLenSubstrNoRepeats(string s, int k) {
// A vector to track used characters, initialized to 26 false values
vector<bool> is_char_used(26, false);
int left = 0; // The start index of the sliding window
int right = 0; // The end index of the sliding window
int result_count = 0; // To count the number of valid substrings
int string_length = s.size(); // The length of the input string
// Iterate over each character using the right index as the window expands
for (; right < string_length; right++) {
// If the current character is already used in the current window
if (is_char_used[s[right] - 'a']) {
// Move the left index to the right until the character at right is not duplicated
do {
is_char_used[s[left] - 'a'] = false;
} while (s[left++] != s[right]);
}
// Mark the current character as used
is_char_used[s[right] - 'a'] = true;
// If the window size is at least k, increment the result count
if (right - left + 1 >= k) {
result_count++;
}
}
return result_count; // Return the number of valid substrings found
}
};
Python
class Solution:
def numKLenSubstrNoRepeats(self, s: str, k: int) -> int:
# A list to track used characters, initialized to 26 False values
is_char_used = [False] * 26
left = 0 # The start index of the sliding window
right = 0 # The end index of the sliding window
result_count = 0 # To count the number of valid substrings
string_length = len(s) # The length of the input string
# Iterate over each character using the right index as the window expands
while right < string_length:
# If the current character is already used in the current window
if is_char_used[ord(s[right]) - ord('a')]:
# Move the left index to the right until the character at right is not duplicated
while s[left] != s[right]:
is_char_used[ord(s[left]) - ord('a')] = False
left += 1
left += 1
# Mark the current character as used
is_char_used[ord(s[right]) - ord('a')] = True
# If the window size is at least k, increment the result count
if right - left + 1 >= k:
result_count += 1
right += 1
return result_count # Return the number of valid substrings found
Complexity
Time complexity: $O(n)$
The algorithm utilizes a sliding window approach across the string. Theright
pointer iterates over each character in the string exactly once, which gives a complexity of $O(n)$ where $n$ is the length of the string $s$. Although there is an inner loop that moves theleft
pointer, each character is handled at most twice (once when added to the window and once when removed), ensuring the cumulative operations inside this loop remain $O(n)$.Space complexity: $O(1)$
The algorithm uses a fixed-size vectoris_char_used
of length 26 to track the usage of each lowercase English letter. This space requirement does not scale with the input size, making the space complexity $O(1)$. The integers forleft
,right
,result_count
, andstring_length
also contribute a constant amount of space.
Disclaimer: All reference materials on this website are sourced from the internet and are intended for learning purposes only. If you believe any content infringes upon your rights, please contact me at csnote.cc@gmail.com, and I will remove the relevant content promptly.
Feedback Welcome: If you notice any errors or areas for improvement in the articles, I warmly welcome your feedback and corrections. Your input will help this blog provide better learning resources. This is an ongoing process of learning and improvement, and your suggestions are valuable to me. You can reach me at csnote.cc@gmail.com.