无重复字符的最长子串 题解
##1. 题目
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
##2.题解
###①暴力法:(该法会超时)
解题思路:
(1)遍历每个子串,判断里面是否有重复字符,无重复字符则更新最长不重复字符子串长度,有重复就继续遍历直至遍历完成
(2)编写判断字符串是否有重复字符函数isContainSubstring(String s,int start,int end)
(3)编写返回最大无重复子串字符长度的函数lengthOfLongestSubstring(String s)
```java
class Solution {
public int lengthOfLongestSubstring(String s) {
int no_duplicate_length=0;//无重复字符的最长子串长度
int length=s.length();//字符串总长度
for(int i=0;i<length;i++){//i为字符串起始位置
for(int j=i;j<length;j++){//j为字符串终止位置
if(isContainSubstring(s,i,j+1))//判断子串是否有重复字符
no_duplicate_length=Math.max(j-i+1,no_duplicate_length);//无重复字符,更新no_duplicate_length
}
}
return no_duplicate_length;
}
public boolean isContainSubstring(String s,int start,int end){//判断字符串是否有重复字符
Set<Character> hashSet=new HashSet<Character>();
for(int i=start;i<end;i++){//遍历每一个字符
Character ch=s.charAt(i);
if(hashSet.contains(ch))//判断遍历的字符是否重复
return false;//重复则返回false
hashSet.add(ch);//不重复将该遍历的字符加入hashSet
}
return true;//遍历完整个字符串都不重复
}
}
###②滑动窗口法(运行时间更短,复杂度更低)
解题思路:
遍历字符串起始位置i,从i往后遍历j,检查j位置字符是否重复,遇到重复字符则表示i开始的字符串已经最长了,更新无重复子串长度,让i++重复上述操作。
class Solution {
public int lengthOfLongestSubstring(String s) {
Set<Character> hashSet=new HashSet<Character>();
int ans=0;//无重复字符最长字串长度
int i=0,j=0;//滑动窗口的左右边界
int length=s.length();//字符串长度
for(;i<length&&j<length;){//子串左边界i=length说明已经遍历到头了,右边界j=length说明最长子串已出现
if(!hashSet.contains(s.charAt(j))){//判断右边界j位置字符是否重复
hashSet.add(s.charAt(j));//不重复则将该位置字符加入集合
j++;//右边界j+1,放在这里避免只有一个字符的字符串的j不能+1
ans=Math.max(j-i,ans);//更新子串长度
}
else{//有重复,则遍历下一个i
hashSet.remove(s.charAt(i));//从集合中移除上一个i
i++;//遍历下一个i
}
}
return ans;
}