Idea is that, while we traverse form left to right if we see a character at position j is a duplicate of a character at a position i < j on the left then we know that we can't start the substring from i anymore. So, we need to start a new substring from i+1 position. While doing this we also need to update the length of current substring and start of current substring. Important part of this process is to make sure that we always keep the latest position of the characters we have seen so far. Below is a simple O(n) implementation of this logic.

```
public class Solution {
public int lengthOfLongestSubstring(String s) {
int lastIndices[] = new int[256];
for(int i = 0; i<256; i++){
lastIndices[i] = -1;
}
int maxLen = 0;
int curLen = 0;
int start = 0;
int bestStart = 0;
for(int i = 0; i<s.length(); i++){
char cur = s.charAt(i);
if(lastIndices[cur] < start){
lastIndices[cur] = i;
curLen++;
}
else{
int lastIndex = lastIndices[cur];
start = lastIndex+1;
curLen = i-start+1;
lastIndices[cur] = i;
}
if(curLen > maxLen){
maxLen = curLen;
bestStart = start;
}
}
return maxLen;
}
}
```