class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        str_length = len(s)

        if str_length == 0:
            return 0

        characters = dict()  # 특정 문자의 마지막 출몰 인덱스 ex) {'a': 0, 'b': 1, 'c': 2}
        tail = 0
        head = 0
        result = 0

        while head < str_length:
            ch = s[head]

            # characters[ch](인덱스)가 tail 보다 작은 경우 옛날 일이라 별 상관 없음
            if ch in characters and characters[ch] >= tail:
                # 바로 다음 인덱스에서 다시 시작
                tail = characters[ch] + 1

            characters[ch] = head
            result = max(result, head - tail + 1)  # 현재 길이가 최대값이라면 결과 업데이트

            head += 1

        return result


assert (Solution().lengthOfLongestSubstring("abcabcbb") == 3)
assert (Solution().lengthOfLongestSubstring("bbbbb") == 1)
assert (Solution().lengthOfLongestSubstring("pwwkew") == 3)
assert (Solution().lengthOfLongestSubstring("") == 0)
