```
class Solution:
# @return an integer
def lengthOfLongestSubstring(self, s):
maxlength=0
templength=0
charused={}
start=0
for i in range(len(s)):
if s[i] not in charused or charused[s[i]]<start:
charused[s[i]]=i
templength+=1
maxlength=max(maxlength,templength)
elif s[i] in charused:
start=charused[s[i]]+1
charused[s[i]]=i
templength=i-start+1
maxlength=max(maxlength,templength)
return maxlength
```

the current substring is the longest substring without duplicate that ends at i, the current visit element .

by moving forward i, i=i+1, we scan the entire string s.

After moving i forward, If we find a duplicate in the current substring, we look up the dictionary to return the duplicate position, and recalculates the substring length. Also it moves the start of the current substring. The invariant here is:

the current substring has no duplicate.

By recording the length of all "current" substrings and find the max, we have the max substring without duplicates.

The hidden argument here is, the max length substring , call it s*, must be a "current" substring, when we visit the last element of s*.