class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @return int整型
     */
    int lengthOfLongestSubstring(string s) {
        // write code here
        // 滑动窗口,定义左右指针,没重复的字符就右指针右移扩大窗口,
        // 窗口内出现重复字符,左指针移动到重复字符的下一个位置上
        // 每一步都更新最长子字符串长度
        // 存储字符和最新的索引
        unordered_map<char, int> charIndexMap;
        int maxLength = 0; // 最长子字符串长度
        int left = 0;

        for (int right = 0; right < s.length(); ++right) {
            char currentChar = s[right];

            // 如果字符已经存在且其索引还在窗口范围内,移动左指针
            if (charIndexMap.find(currentChar) != charIndexMap.end()
                && charIndexMap[currentChar] >= left) {
                    left = charIndexMap[currentChar] + 1;
                }
            
            // 更新字符最新的索引
            charIndexMap[currentChar] = right;

            // 计算当前无重复字符子字符串长度
            maxLength = max(maxLength, right - left + 1);
        }

        return maxLength;
    }
};