Longest Substring Without Repeating Characters (LeetCode)
In this page we will solve the problem Longest Substring Without Repeating Characters from LeetCode.
Problem Statement​
Given a string s, find the length of the longest substring without repeating characters.
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 * 10^4sconsists of English letters, digits, symbols and spaces.
Solution for Longest Substring Without Repeating Characters​
Intuition and Approach​
We can solve this problem using the sliding window technique. We will use a hash table to store the characters and their indices. We will also use two pointers, left and right, to define the window. The left pointer will point to the start of the window, and the right pointer will point to the end of the window.
We will iterate over the string s using the right pointer. If the character at the right pointer is not in the hash table, we will add it to the hash table with its index. We will then calculate the length of the current window by subtracting the left pointer from the right pointer and update the maximum length if needed.
If the character at the right pointer is already in the hash table, we will move the left pointer to the right of the last occurrence of the character. We will also update the index of the character in the hash table.
We will continue this process until we reach the end of the string s. The maximum length of the substring without repeating characters will be the answer.
Algorithm​
- Initialize an empty hash table
charIndexto store the characters and their indices. - Initialize the
leftandrightpointers to 0. - Initialize the
maxLengthvariable to store the maximum length of the substring without repeating characters. - Iterate over the string
susing therightpointer:- If
s[right]is not incharIndex, add it to the hash table with its index. - Calculate the length of the current window and update the
maxLengthif needed. - If
s[right]is already incharIndex, move theleftpointer to the right of the last occurrence ofs[right]. - Update the index of
s[right]in the hash table.
- If
- Continue this process until the end of the string
s. - Return the
maxLength.
Flowchart​
The flowchart below illustrates the steps involved in the algorithm:
Pseudocode​
function lengthOfLongestSubstring(s: string): number
let charIndex = new Map()
let left = 0
let maxLength = 0
for right from 0 to s.length - 1
if s[right] in charIndex
left = max(left, charIndex[s[right]] + 1)
charIndex[s[right]] = right
maxLength = max(maxLength, right - left + 1)
return maxLength
Implementation and Code​
Here is a live code editor for you to play around with the solution:
function LongestSubstringProblem() { const findLongestSubstring = (s) => { let charIndexMap = {}; let left = 0; let maxLength = 0; for (let right = 0; right < s.length; right++) { if (charIndexMap[s[right]] !== undefined) { left = Math.max(left, charIndexMap[s[right]] + 1); } charIndexMap[s[right]] = right; maxLength = Math.max(maxLength, right - left + 1); } return maxLength; }; const testCases = [ { input: "abcabcbb", expected: 3 }, { input: "bbbbb", expected: 1 }, { input: "pwwkew", expected: 3 }, ]; return ( <div> {testCases.map((testCase, index) => ( <div key={index}> <p> <b>Input:</b> {testCase.input} </p> <p> <b>Output:</b> {findLongestSubstring(testCase.input)} </p> <p> <b>Expected:</b> {testCase.expected} </p> <hr /> </div> ))} </div> ); }
Code in Different Languages​
- JavaScript
- Python3
- Java
- C++
- C
- TypeScript
- Other
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
let charIndexMap = {};
let left = 0;
let maxLength = 0;
for (let right = 0; right < s.length; right++) {
if (charIndexMap[s[right]] !== undefined) {
left = Math.max(left, charIndexMap[s[right]] + 1);
}
charIndexMap[s[right]] = right;
maxLength = Math.max(maxLength, right - left + 1);
}
return maxLength;
};
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
char_index_map = {}
left = 0
max_length = 0
for right in range(len(s)):
if s[right] in char_index_map:
left = max(left, char_index_map[s[right]] + 1)
char_index_map[s[right]] = right
max_length = max(max_length, right - left + 1)
return max_length
class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character, Integer> charIndexMap = new HashMap<>();
int left = 0;
int maxLength = 0;
for (int right = 0; right < s.length(); right++) {
if (charIndexMap.containsKey(s.charAt(right))) {
left = Math.max(left, charIndexMap.get(s.charAt(right)) + 1);
}
charIndexMap.put(s.charAt(right), right);
maxLength = Math.max(maxLength, right - left + 1);
}
return maxLength;
}
}
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char, int> charIndexMap;
int left = 0;
int maxLength = 0;
for (int right = 0; right < s.length(); right++) {
if (charIndexMap.find(s[right]) != charIndexMap.end()) {
left = max(left, charIndexMap[s[right]] + 1);
}
charIndexMap[s[right]] = right;
maxLength = max(maxLength, right - left + 1);
}
return maxLength;
}
};
int lengthOfLongestSubstring(char * s){
int charIndexMap[256];
memset(charIndexMap, -1, sizeof(charIndexMap));
int left = 0;
int maxLength = 0;
for (int right = 0; s[right] != '\0'; right++) {
if (charIndexMap[s[right]] != -1) {
left = fmax(left, charIndexMap[s[right]] + 1);
}
charIndexMap[s[right]] = right;
maxLength = fmax(maxLength, right - left + 1);
}
return maxLength;
}
function lengthOfLongestSubstring(s: string): number {
const charIndexMap: Record<string, number> = {};
let left = 0;
let maxLength = 0;
for (let right = 0; right < s.length; right++) {
if (charIndexMap[s[right]] !== undefined) {
left = Math.max(left, charIndexMap[s[right]] + 1);
}
charIndexMap[s[right]] = right;
maxLength = Math.max(maxLength, right - left + 1);
}
return maxLength;
}
- Python3
- Java
- C++
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
n = len(s)
maxLength = 0
charSet = set()
left = 0
for right in range(n):
if s[right] not in charSet:
charSet.add(s[right])
maxLength = max(maxLength, right - left + 1)
else:
while s[right] in charSet:
charSet.remove(s[left])
left += 1
charSet.add(s[right])
return maxLength
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
int maxLength = 0;
Set<Character> charSet = new HashSet<>();
int left = 0;
for (int right = 0; right < n; right++) {
if (!charSet.contains(s.charAt(right))) {
charSet.add(s.charAt(right));
maxLength = Math.max(maxLength, right - left + 1);
} else {
while (charSet.contains(s.charAt(right))) {
charSet.remove(s.charAt(left));
left++;
}
charSet.add(s.charAt(right));
}
}
return maxLength;
}
}
#include <vector>
#include <string>
#include <algorithm>
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if (s.empty()) return 0;
int maxLength = 0;
std::vector<char> seen;
for (char c : s) {
auto it = std::find(seen.begin(), seen.end(), c);
if (it == seen.end()) {
seen.push_back(c);
maxLength = std::max(maxLength, static_cast<int>(seen.size()));
} else {
seen.erase(seen.begin(), it + 1); // Remove characters before the repeated character
seen.push_back(c);
}
}
return maxLength;
}
};
Complexity Analysis​
-
Time Complexity: The time complexity of this solution is , where n is the length of the input string
s. We iterate over the stringsonce using therightpointer. -
Space Complexity: The space complexity of this solution is , where n is the length of the input string
sand m is the size of the character set (e.g., 26 for lowercase English letters). We use a hash table to store the characters and their indices, which can have a maximum of m entries.
Test Cases​
We will test the solution with the sample test cases provided in the problem statement.
- Case 1
- Case 2
- Case 3
Input: s = "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
Input: s = "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
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.