题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
样例
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
算法分析
双指针
- 1、
i
在前,j
在后,[j,i]
区间始终维护的是枚举到i
位置时无重复字符的最长子串,用哈希表记录[j,i]
区间的每个元素的个数 - 2、
i
往前走一格时,直接讲i
位置的元素加入到哈希表中,然后判断i
位置的元素在[j,i]
区间中是否有重复,若有重复则j
往前走一步,并将j
位置的元素数量减1
,当[j,i]
中确保不存在重复元素时,则更新ans
时间复杂度 $O(n)$
Java 代码
class Solution {
public int lengthOfLongestSubstring(String s) {
HashMap<Character,Integer> map = new HashMap<Character,Integer>();
int ans = 0;
//i在前,j在后
for(int i = 0,j = 0;i < s.length();i ++)
{
map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1);
//判断i位置的元素是否有重复,有重复j向前走
while(map.get(s.charAt(i)) > 1)
{
map.put(s.charAt(j), map.get(s.charAt(j)) - 1);
j ++;
}
ans = Math.max(ans, i - j + 1);
}
return ans;
}
}
大佬,这里应该是 j 前 i 后吧