
Problem Statement
The task is to determine the length of the longest substring of a given string s
that does not contain any repeated characters. This substring, by definition, must consist of consecutive characters from s
without the same character appearing more than once. Understanding the maximum length of such a substring in any given string helps in various applications like data compression, cryptography, and complex pattern matching scenarios where uniqueness is key.
Examples
Example 1
Input:
s = "abcabcbb"
Output:
3
Explanation:
The answer is "abc", with the length of 3.
Example 2
Input:
s = "bbbbb"
Output:
1
Explanation:
The answer is "b", with the length of 1.
Example 3
Input:
s = "pwwkew"
Output:
3
Explanation:
The answer is "wke", with the length of 3. Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
Constraints
0 <= s.length <= 5 * 104
s
consists of English letters, digits, symbols and spaces.
Approach and Intuition
The problem of finding the longest substring without repeating characters can be approached efficiently using the "sliding window" technique combined with hashing. The core idea is to maintain a window using two pointers and expand or contract this window based on the presence of duplicate characters.
Steps
- Initialize two pointers,
start
andend
, which represent the beginning and the end of our window, respectively, both set to the beginning of the string initially. - Use a hash map or a set to keep track of the characters and their indices within the window.
- Expand the end pointer to explore new characters and add them to the hash map. If a character is unique, increase the window size.
- If a character is repeated, meaning it is already present in the hash map, increment the start pointer to shrink the window from the left until the duplicate is removed. This involves possibly removing characters from the hash map or updating their indices.
- For each position of
end
, check the length of the windowend - start + 1
and update the maximum length if it's the longest found so far. - Continue this until the end pointer has traversed the entire string.
Explanation through the examples
- For
s = "abcabcbb"
:- Traverse through each character and adjust the window when 'a' repeats, leading us to realize that "abc" is the longest unique substring, thus leading to a maximum length of 3.
- For
s = "bbbbb"
:- Since the same character 'b' repeats, the window never expands beyond a length of 1.
- For
s = "pwwkew"
:- Move the pointer from 'w' to 'k' when 'w' repeats and recognize "wke" as the longest unique substring. Though "pwke" is longer, it is not a continuous substring without repeats, making "wke" (length 3) the answer here.
This sliding window approach ensures that each character is processed once, making the solution efficient with a linear time complexity, which is crucial given the potential length of the string as stated in the constraints.
Solutions
- C++
- Java
- C
- JavaScript
- Python
class Solution {
public:
int maxUniqueSubstrLength(string str) {
int length = int(str.length()), maxLen = 0;
unordered_map<char, int> indexMap;
for (int end = 0, start = 0; end < length; end++) {
if (indexMap[str[end]] > 0) {
start = max(indexMap[str[end]], start);
}
maxLen = max(maxLen, end - start + 1);
indexMap[str[end]] = end + 1;
}
return maxLen;
}
};
The provided C++ code defines a function to determine the length of the longest substring without repeating characters in a given string. Below is an overview of how this implemented function works:
- Initialize two integers for tracking the longest length and the current window of the non-repeating substring (
maxLen
andstart
respectively) and an unordered map (indexMap
) for storing the character's last known index. - Loop through the string using a
for
loop, with the variableend
serving as the ending index pointer for your current substring under evaluation. - Within the loop, check if the current character is already in the map and adjust the starting index (
start
) accordingly, ensuring no repeated characters are in the current substring by moving the start index past the last occurrence of the current character. - The loop also calculates the maximum length so far by comparing the current substring length (from
start
toend
) with the previously found maximum lengths. - Each character and its index (incremented by one) are stored in the
indexMap
. This allows you to maintain an updated index for each character that adjusts thestart
when a repeat character is found. - The function concludes by returning
maxLen
, which contains the length of the longest substring without repeating characters discovered through this process.
This function provides an efficient solution using a sliding window technique combined with hash mapping, ensuring a time complexity close to O(n), where n is the number of characters in the string. This efficiency comes from the fact that each index is processed only once with constant-time operations due to unordered_map.
public class Solution {
public int findMaxLengthSubstring(String str) {
int length = str.length(), maxLen = 0;
Map<Character, Integer> indexMap = new HashMap<>();
for (int end = 0, start = 0; end < length; end++) {
if (indexMap.containsKey(str.charAt(end))) {
start = Math.max(indexMap.get(str.charAt(end)), start);
}
maxLen = Math.max(maxLen, end - start + 1);
indexMap.put(str.charAt(end), end + 1);
}
return maxLen;
}
}
The provided Java solution efficiently tackles the problem of finding the longest substring without repeating characters in a given string. The solution uses a sliding window algorithm represented by two pointers, start
and end
, and a hash map indexMap
that keeps track of the characters and their latest indices in the string.
Here's a concise breakdown of how the solution operates:
- Initialize
maxLen
to zero to store the maximum length of substring found andindexMap
to store characters and their indices. - Iterate through the string with the
end
pointer:- Check if the current character at the
end
pointer exists in theindexMap
. - If it exists and the stored index is greater than or equal to
start
, updatestart
to the maximum value between the currentstart
and the character's last index fromindexMap
to avoid including repeated characters. - Calculate the length of the current substring by
end - start + 1
and updatemaxLen
if it's the longest found so far. - Update
indexMap
with the current character and its index +1.
- Check if the current character at the
- Return
maxLen
which contains the length of the longest substring without repeating characters.
This approach ensures that each character in the string is processed once, leading to a time complexity of O(n), where n is the length of the string. The space complexity is O(min(m, n)) where m is the size of the character set. With these mechanics, the algorithm balances efficiency and clarity, making it effective for strings of considerable length.
int substringUniqueLength(char* s) {
int lastPos[256] = {0}; // Array for mapping character to last position
int longest = 0;
int start = 0;
int strLen = strlen(s);
for (int end = 0; end < strLen; end++) {
int character = (int)s[end];
if (lastPos[character] > 0) {
start = max(start, lastPos[character]);
}
longest = max(longest, end - start + 1);
lastPos[character] = end + 1;
}
return longest;
}
int max(int x, int y) { return (x > y) ? x : y; }
This program, written in C, computes the length of the longest substring without repeating characters from a given string. The function substringUniqueLength
uses an integer array lastPos
to track the last position of each character within the ASCII range. Here is how it achieves this:
- Initialize an array
lastPos
of size 256 to store the last positions of characters, initially filled with zeros. - Define variables
longest
to keep track of the maximum length of substring found, andstart
to mark the beginning of a possible substring. - Execute a loop from
start
to the end of the string. For each character:- Convert the character
s[end]
to its ASCII equivalentcharacter
. - If the character was seen before and is within the current substring, update the
start
to the maximum ofstart
and last seen position of the character. - Calculate the potential longest substring from the current
start
toend
and compare it with the longest found so far. - Update the last seen position of the current character.
- Convert the character
- Return the length of the longest substring found.
The helper function max
is used to determine the greater of two numbers, simplifying the process of updating lengths and starting positions. This approach ensures that each character's position is updated only while it is part of the current substring, optimizing the search for the longest possible substring without duplicates.
var longestSubstringWithoutRepeating = function (str) {
let indexMap = new Map();
let maxLength = 0;
let start = 0;
for (let end = 0; end < str.length; end++) {
if (indexMap.has(str[end])) {
start = Math.max(indexMap.get(str[end]), start);
}
maxLength = Math.max(maxLength, end - start + 1);
indexMap.set(str[end], end + 1);
}
return maxLength;
};
The solution provided is a JavaScript function designed to determine the length of the longest substring without repeating characters in a given string. It efficiently handles this task by using a sliding window technique combined with a Map to track the most recent index of each character.
- Inside the function
longestSubstringWithoutRepeating
, two main variables are initialized:indexMap
for storing character indices, andmaxLength
to keep track of the maximum length of substring found. - The loop runs through each character in the string. Inside the loop:
- Check if the character already has a recorded index greater than the current
start
position. If so, updatestart
to the recorded index to ensure the window only contains unique characters. - Update
maxLength
to store the size of the current window if it is the largest found so far. - Record the index of the current character in the map.
- Check if the character already has a recorded index greater than the current
- After processing all characters,
maxLength
will contain the length of the longest substring without repeating characters, and the function returns this value.
This approach ensures efficient computation, updating the necessary variables to maintain non-repeated characters within a dynamically resizing window, leveraging the random-access capabilities of the JavaScript Map to immediately locate indices of characters.
class Solution:
def findMaxNonRepeatingSubstrLen(self, input_string: str) -> int:
string_length = len(input_string)
max_length = 0
index_map = {}
start_index = 0
for end_index in range(string_length):
if input_string[end_index] in index_map:
start_index = max(index_map[input_string[end_index]], start_index)
max_length = max(max_length, end_index - start_index + 1)
index_map[input_string[end_index]] = end_index + 1
return max_length
The Python solution provided calculates the length of the longest substring without repeating characters in a given string using a sliding window technique and a hash map. The method findMaxNonRepeatingSubstrLen
accepts a string and processes it to determine the longest unique substring. Below outlines how the solution operates:
- Initialize
string_length
to hold the length of the input string. max_length
is used to track the length of the longest non-repeating substring found so far.index_map
maps characters to their latest index plus one in the string.start_index
is used to maintain the starting index of the current window of characters that are being considered.
As you iterate over each character (end_index
as the current position):
- Update
start_index
to either its current value or the value indexed inindex_map
for the current character, depending on which is greater. This helps in adjusting the window size whenever a repeating character is found. - Update
max_length
to be the maximum value between itself and the length of the current window (end_index - start_index + 1
). - Store or update in
index_map
the next index for the current character (end_index + 1
).
The method concludes by returning max_length
, which at the end of the loop will contain the length of the longest substring without repeating characters. This approach efficiently solves the problem with a time complexity of O(n), where n is the length of the string, using a single pass through the string and constant space relative to the character set size.
No comments yet.