【每日一题】LeetCode 3.最长无重复字符的子串(哈希表、字符串、滑动窗口)
题目描述
给定一个字符串 s
,找出其中不含有重复字符的最长子串的长度。需要注意的是,要求的是子串的长度,而不是子序列。
思路分析
这个问题可以通过使用滑动窗口的方法来解决。具体步骤如下:
- 初始化:定义两个指针
left
和right
分别代表子串的开始和结束位置,以及一个哈希表map
来存储字符及其索引。 - 遍历字符串:遍历字符串,使用
right
指针扩展窗口,并将遇到的字符及其索引存入哈希表。 - 处理重复:如果遇到重复字符,即该字符已存在于哈希表中,那么需要移动
left
指针,直到窗口内没有重复字符。同时更新left
指针的位置为重复字符索引加1,确保窗口内不包含重复字符。 - 更新最大长度:在每次扩展窗口后,计算当前无重复字符子串的长度,并更新最大长度
maxLen
。 - 返回结果:遍历完成后,返回最大长度
maxLen
。
输入示例
- 示例 1:
- 输入:
s = "abcabcbb"
- 输出:
3
- 输入:
- 示例 2:
- 输入:
s = "bbbbb"
- 输出:
1
- 输入:
- 示例 3:
- 输入:
s = "pwwkew"
- 输出:
3
- 输入:
代码实现
import java.util.HashMap;
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
int maxLen = 0; // 用于存储最长无重复字符子串的长度
int left = 0; // 子串的左边界
char[] chars = s.toCharArray(); // 将字符串转换为字符数组
HashMap<Character, Integer> map = new HashMap<>(); // 存储字符及其索引的哈希表
for (int right = 0; right < chars.length; right++) {
char c = chars[right];
// 如果字符已存在于哈希表中,且索引小于左边界,则更新左边界
if (map.containsKey(c)) {
left = Math.max(left, map.getOrDefault(c, -1) + 1);
}
// 将当前字符及其索引存入哈希表
map.put(c, right);
// 更新最长无重复字符子串的长度
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen;
}
}