【LeetCode】3. 无重复字符的最长子串
解题思路
使用哈希表存储字符以及对应的索引,窗口右边界right
不断右移将新元素加入窗口,如果遇到重复的元素,就将窗口左边界left
更新为 max(left, 重复元素的下一个位置),取两者之中的最大值是防止左边界left
向左移动。
错误的思想: 遇到重复的元素,将窗口左边界left
更新为 重复元素的下一个位置。以字符串 "google" 为例,当right
移动到索引2的时候,字符 'o' 重复,将left
更新为map.get('o') + 1 = 2
,当right
移动到索引3的时候,字符 'g' 重复,将left
更新为map.get('g') + 1 = 1
。此时出现left
向左移动的情况,窗口字符串为 "oog"显然是错误的,所以应将left
更新为max(left, map.get('g') + 1) = 2
。
代码
class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character, Integer> map = new HashMap<>();
int res = 0, left = 0, right = 0;
while (right < s.length()) {
char c = s.charAt(right);
if (map.containsKey(c)) {
left = Math.max(left, map.get(c) + 1);
}
map.put(c, right++);
res = Math.max(res, right - left);
}
return res;
}
}
复杂度分析
- 时间复杂度:O(N),其中N为字符串的长度。
- 空间复杂度:O(M),其中M为字符集的大小。