2026-06-22
Sliding Window - Longest Substring
General coding question around how to find the longest substring of unique characters in a given string.
When given a string, return the length of the longest distinct list of characters in the string. Example: abcdeba -> returns 5 for 'abcde'.
This can be solved 2 different ways.
First way
Set the starting point and ending point at index 0 for the substring. Also create an array of 26 positions (1 for each letter of the alphabet) and set all the values to false, this array will be the mechanism for seeing if the substring has visited the letter already.
Loop through the full string, 1 character at a time and checking if the next character exists in the array of letters setting it's array position to true as you move past them. As you loop through you'll be setting the maximum value of the substring along the way for each movement of the end point. Increase the value of the end point until you find a letter you've already visited.
Once the endpoint finds a letter it has visited, then start looping through the full string from the starting point index. Set the index value of the current starting point letter to false and loop again until you've reach the endpoint's index and have set that to false as well, breaking the looping process. Now the endpoint can continue to loop until it has reached the end of the process.
function longestUniqueSubstr(s) {
if (s.length === 0 || s.length === 1)
return s.length;
let res = 0;
let vis = new Array(26).fill(false);
// left and right pointer of sliding window
let left = 0, right = 0;
while (right < s.length) {
while (vis[s[right].charCodeAt(0) - 'a'.charCodeAt(0)] === true) {
vis[s[left].charCodeAt(0) - 'a'.charCodeAt(0)] = false;
left++;
}
vis[s[right].charCodeAt(0) - 'a'.charCodeAt(0)] = true;
res = Math.max(res, (right - left + 1));
right++;
}
return res;
}
// Driver Code
const s = "geeksforgeeks";
console.log(longestUniqueSubstr(s));
Second way
Similar to the first way, keep track of the start and end values of the substring. The big dfference this time is to keep track of the indexes of the letters visited as opposed to IF they've been visited. Note the lastIndex array has been filled with -1s instead of falses.
Here the loop starts by reviewing if the aplhabetic index of the first character is bigger than 0 and moves forward with the largest of the two. It then updates the total length of the substring so far. Finally setting the index position of the endpoint to the letter found in the lastIndex letter array (lastIndex[g] == [0]) => (lastIndex[e] == [1]) => (lastIndex[e] == [2])...
As it loops it checks the lastIndex array to find the current character's position to see if it's larger than the current start point. So if starting point was at 0, but you came across the same letter, that letter would have had it's index set to be a previous endpoint. All you do is set it to that index + 1 to have the new start of the next substring.
function longestUniqueSubstr(s) {
const n = s.length;
let res = 0;
// last index of all characters is initialized as -1
const lastIndex = new Array(26).fill(-1);
// Initialize start of current window
let start = 0;
// Move end of current window
for (let end = 0; end < n; end++) {
start = Math.max(start, lastIndex[s.charCodeAt(end) - 'a'.charCodeAt(0)] + 1);
// Update result if we get a larger window
res = Math.max(res, end - start + 1);
// Update last index of s[end]
lastIndex[s.charCodeAt(end) - 'a'.charCodeAt(0)] = end;
}
return res;
}
// Driver Code
const s = "geeksforgeeks";