Intuition
Keep a window [l, r] over the string such that it never contains a duplicate.
When you find s[r] was seen inside the current window, jump l just past
the previous occurrence — that's the smallest move that restores the invariant.
Explanation
Approach
last = {}maps char to its latest index.- Initialize
l = 0,best = 0. - For each
rfrom0ton-1:- If
s[r] in lastandlast[s[r]] >= l: setl = last[s[r]] + 1. - Update
last[s[r]] = r. best = max(best, r - l + 1).
- If
Walk-through
s = "abcabcbb"
| r | char | l | window | best |
|---|---|---|---|---|
| 0 | a | 0 | a | 1 |
| 1 | b | 0 | ab | 2 |
| 2 | c | 0 | abc | 3 |
| 3 | a | 1 | bca | 3 |
| 4 | b | 2 | cab | 3 |
| 5 | c | 3 | abc | 3 |
| 6 | b | 5 | cb | 3 |
| 7 | b | 7 | b | 3 |
Implementation
import java.util.*;
class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character, Integer> last = new HashMap<>();
int l = 0, best = 0;
for (int r = 0; r < s.length(); r++) {
char ch = s.charAt(r);
if (last.containsKey(ch) && last.get(ch) >= l) {
l = last.get(ch) + 1;
}
last.put(ch, r);
best = Math.max(best, r - l + 1);
}
return best;
}
}