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

浙公网安备 33010602011771号