题目描述:
Given a string, find the length of the longest substring without repeating characters.
Example 1:
Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc"
, with the length of 3.
Example 2:
Input: "bbbbb"
Output: 1
Explanation: The answer is "b"
, with the length of 1.
Example 3:
Input: "pwwkew" Output: 3 Explanation: The answer is"wke"
, with the length of 3. Note that the answer must be a substring,"pwke"
is a subsequence and not a substring.
思路1:滑动窗口
用hashset来查找目前为止最长的无重复子串,用快指针fast来查找它所指的字符是否出现在Hashset中,
若没有出现,将其加入到HashSet中。并将fast后移1位,同时最大长度+1.
否则,用慢指针删除头部直到可以将当前快指针所指向的字符加入到HashSet中。
实现1:
import java.util.HashSet;
class Solution {
public int lengthOfLongestSubstring(String s) {
int slow=0,fast=0,ret=0;
HashSet<Character> set=new HashSet<>();
while(fast<s.length()){
if(!set.contains(s.charAt(fast))){
set.add(s.charAt(fast++));
ret=Math.max(ret,set.size());
}else{
set.remove(s.charAt(slow++));
}
}
return ret;
}
}
遍历字符串,使用 head 来标记当前子串的右侧头位置,tail 来标记当前子串的左侧尾位置,sub[tail,head]表示当前子串
(1)当sub[tail,head]中所有字符都不重复时,则head++
(2)当sub[tail,head]中包含重复字符时,则tail++,直到所有字符都不重复为止
(3)根据当前不重复子串,更新最大长度res
实现:
import java.util.HashSet;
class Solution {
public int lengthOfLongestSubstring(String s) {
HashSet<Character> set=new HashSet<>();
int ret=0;
int tail=0;
for(int head=0;head<s.length();head++){
while(tail<=head&&set.contains(s.charAt(head))){
set.remove(s.charAt(tail++));
}
set.add(s.charAt(head));
ret=Math.max(ret, set.size());
}
return ret;
}
}
思路2:TwoSum的思想
用HashMap存储字符及其对应的索引。遍历字符串,若遍历到的字符和之前不重复,则将该字符及其对应的索引加入HashMap中,并更新最大长度。若存在重复的,则获得之前该字符对应的索引,并将该索引赋值给尾部后更新最大长度。
import java.util.HashMap;
class Solution {
public int lengthOfLongestSubstring(String s) {
int maxLen=0;
int tail=-1;
HashMap<Character,Integer> map=new HashMap<>();
for(int i=0;i<s.length();i++){
Character ch=s.charAt(i);
Integer old=map.get(ch);
map.put(ch,i);
if(old!=null&&old>tail){
tail=old;
}
maxLen=Math.max(maxLen,i-tail);
}
return maxLen;
}
}