Simple Explanation | Concise | Thinking Process & Example
Lets start with the following example: \n\nAssume you had no repeating characters (In below example, just look at first three characters)\n\nWe take two pointer
Lets start with the following example: \n\n**Assume you had no repeating characters** (In below example, just look at *first three* characters)\n\nWe take two pointers, `l` and `r`, both starting at `0`. At every iteration, we update the longest string with non-repeating characters found = `r-l+1` and just keep a note of which character we see at which index\n\n\n<img src="https://assets.leetcode.com/users/images/3e7b9848-1d57-42ed-9629-59f14cfcce89_1595114117.3901849.png" width=400/>\n\n\n```python\n    def lengthOfLongestSubstringSimpler(self, s):\n        seen = {}\n        left, right = 0, 0\n        longest = 1\n        while right < len(s):\n            longest = max(longest, right - left + 1)\n            seen[s[right]] = right\n            right += 1\n        return longest\n```\n\nAfter 3 iterations, if you were keeping a map of when you last saw the character, you\'d have something like this:\n\n<img src="https://assets.leetcode.com/users/images/2f60312a-d377-4786-9449-4a95210f72e2_1595114189.5949714.png" width=300/>\n\nat this point, `longest = r-l+1 = 2 - 0 + 1 = 3`\n\nNow, lets face it - our string _does_ have repeating characters. We look at index 3, we\'re realizing we\'ve seen `a` before. So we now, we can\'t just calculate the value of `longest` like we were doing before. We need to make sure our left pointer, or `l`, is at least past the index where we last saw `a` , thus - we move `l ` to ` seen[right]+1`. We also update our map with last seen of `a` to `3`\n\n<img src="https://assets.leetcode.com/users/images/b7aaad14-993b-47e9-af01-441bbc5dfe20_1595114261.38747.png" width=300/>\n\nAnd this interplay goes on\n\n<img src="https://assets.leetcode.com/users/images/a22de24e-9e66-4e21-ab33-2ac06ce1d0cb_1595114354.4211376.png" width=300/>\n\n\n```python\n    def lengthOfLongestSubstring(self, s):\n        """\n        :type s: str\n        :rtype: int \n        """\n        if len(s) == 0:\n            return 0\n        seen = {}\n        left, right = 0, 0\n        longest = 1\n        while right < len(s):\n            if s[right] in seen:\n                left = seen[s[right]]+1\n            longest = max(longest, right - left + 1)\n            seen[s[right]] = right\n            right += 1\n        return longest\n```\n\nLife was good, until this test case came into our lives:\n`abba`\n\n<img src="https://assets.leetcode.com/users/images/cce6e442-6d18-4971-bcf2-d2c59ea11a51_1595115276.967406.png" width=200/>\n\nAnd we realised, after 4 iterations, our left pointer was to be moved `seen[s[right]]+1 = seen[a] + 1 = 1` - wait what, left was to move back ? That doesn\'t sound correct - that\'d give us longest to be 3 (bba) which is NOT CORRECT\n\nThus, we need to ensure that `l` always goes to the right of it, or just stays at its position\n\nIn other words;\n\n```python\nclass Solution(object):\n    def lengthOfLongestSubstring(self, s):\n        """\n        :type s: str\n        :rtype: int abcabcbb\n        """\n        if len(s) == 0:\n            return 0\n        seen = {}\n        left, right = 0, 0\n        longest = 1\n        while right < len(s):\n            if s[right] in seen:\n                left = max(left,seen[s[right]]+1)\n            longest = max(longest, right - left + 1)\n            seen[s[right]] = right\n            right += 1\n            print(left, right, longest)\n        return longest\n```\n\nThanks, and don\'t forget to upvote if it helped you !\n\n\n\n**BONUS** Trying to be a strong Java Developer ? Checkout this [awesome hands-on series](https://abhinandandubey.github.io/posts/tags/Advanced-Java-Series) with illustrations! \n
['Python', 'Python3']