3. 无重复字符的最长子串

image

3. 无重复字符的最长子串

思路

  1. 滑动窗口:使用两个指针 leftright 表示当前子串的左右边界。right 指针向右扩展窗口,left 指针在遇到重复字符时收缩窗口。
  2. 哈希表记录字符最后出现位置:用一个字典 charIndexMap 存储每个字符最后出现的索引。当 right 指针遇到重复字符时,通过字典快速定位重复字符的上一次出现位置,并将 left 指针移动到该位置的下一位,确保窗口内无重复字符。
  3. 更新最大长度:在每次扩展窗口后(即 right 指针移动后),计算当前窗口长度 right - left + 1,并更新最大长度 maxLength

复杂度分析

  • 时间复杂度

    O(n) ,其中 n 是字符串长度。每个字符最多被访问两次(right 指针遍历一次,left 指针跳跃移动)。

  • 空间复杂度

    O(min(n, m)) ,其中 m 是字符集大小(例如 ASCII 为 256)。最坏情况下需要存储所有字符的索引。

代码

import java.util.HashMap;

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        }
        
        HashMap<Character, Integer> charIndexMap = new HashMap<>();
        int left = 0; // 窗口左边界
        int maxLength = 0; // 最长子串长度
        
        for (int right = 0; right < s.length(); right++) {
            char currentChar = s.charAt(right);
            
            // 如果字符已存在且在窗口内,移动左边界
            if (charIndexMap.containsKey(currentChar) {
                // 确保左边界不会向左回退(取较大值)
                left = Math.max(left, charIndexMap.get(currentChar) + 1);
            }
            
            // 更新字符的最新位置
            charIndexMap.put(currentChar, right);
            
            // 计算当前窗口长度并更新最大值
            maxLength = Math.max(maxLength, right - left + 1);
        }
        
        return maxLength;
    }
}
posted @ 2025-07-25 21:15  quanht  阅读(8)  评论(0)    收藏  举报