Skip to main content

2. Longest Substring Without Repeating Characters

LC3

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 * 104
  • sΒ consists of English letters, digits, symbols and spaces.

Approach 1: Brute Force​

Intuition​

Check all the substring one by one to see if it has no duplicate character.

Implementation​

class Solution {
lengthOfLongestSubstring(s) {
const n = s.length;

let res = 0;
for (let i = 0; i < n; i++) {
for (let j = i; j < n; j++) {
if (this.checkRepetition(s, i, j)) {
res = Math.max(res, j - i + 1);
}
}
}

return res;
}

checkRepetition(s, start, end) {
const chars = new Set();

for (let i = start; i <= end; i++) {
const c = s[i];
if (chars.has(c)) {
return false;
}
chars.add(c);
}

return true;
}
}

// Example usage:
const solution = new Solution();
const result = solution.lengthOfLongestSubstring("abcabcbb");
console.log(result);

Complexity Analysis​

Time complexity : O(n^3)

Approach 2: Sliding Window​

Intuition​

Given a substring with a fixed end index in the string, maintain a Set to record the element which have already occurred in the string.

  • Use two pointers left and right and a variable len to store length
  • Use Set to record visited characters s[right]
  • Iterate over all the elements while right<s.length
  • check if s[right] exists in set with st.has(s[right]
  • if exists, move left++ and remove s[left] from set with st.delete(s[left])
  • if doesn't exist increase len = max(len, right-left+1), add s[right] to set and increment right
  • return len

Code​

// JS Solution
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
const st = new Set();
let right = 0;
let left = 0;
let len = 0;
while (right < s.length) {
if (st.has(s[right])) {
st.delete(s[left]);
left++;
} else {
len = Math.max(len, right-left+1);
st.add(s[right]);
right++;
}
}
return len;

};

Complexity Analysis​

Time complexity : O(n^2)

Approach 3: Sliding Window Optimized​

Intuition​

Given a substring with a fixed end index in the string, maintain a HashMap to record the frequency of each character in the current substring. If any character occurs more than once, drop the leftmost characters until there are no duplicate characters.

Code​

class Solution {
lengthOfLongestSubstring(s) {
const n = s.length;
let res = 0;
const mp = new Map();

for (let j = 0, i = 0; j < n; j++) {
if (mp.has(s[j]) && mp.get(s[j]) > 0) {
i = Math.max(mp.get(s[j]), i);
}
res = Math.max(res, j - i + 1);
mp.set(s[j], j + 1);
}

return res;
}
}

// Example usage:
const solution = new Solution();
const result = solution.lengthOfLongestSubstring("abcabcbb");
console.log(result);

Complexity Analysis​

Time complexity : O(n)

Space complexity : O(min(m,n)). Same as the previous approach.​