LeetCode第3题---无重复字符的最长子串
题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
暴力解题法:
首先,我们假设我们有一个函数,可以判断一个字符串中是否有相同的字符,allUnique();
然后我们再把这个string的所有可能的情况都截取下来,放进去这个函数里面判断,最后求得最大的值就可以了。
class Solution {
//假设我们有一个函数,可以来判断这个字符串的单词都是唯一的,unique()
public boolean allUnique(String s,int start,int end){
//创建一个字符hashSet来存储
Set<Character> set = new HashSet<>();
for (int i = start; i < end; i++) {
Character ch = s.charAt(i);
if (set.contains(ch)) return false;
set.add(ch);
}
return true;
}
public int lengthOfLongestSubstring(String s) {
//有一个num来计数
int num=0;
/*
*从第i个到第length()-1个,结束位置从i+1个到length()
*/
for(int i=0;i<s.length();i++){
for(int j=i+1;j<=s.length();j++){
if(allUnique(s,i,j)) num=Math.max(num,j-i);
}
}
return num;
}
}
但是,这种方法时间太久了,系统不通过。
滑动窗口法:
一个很厉害的想法,滑动窗口法:
我们先举一个例子:
abccd
一开始指针i和指针j都指向a,
字符串(java里我们用一个hashSet存储)为a,还没有重复,我们记录长度(和max比较),移动j。
set变为ab,还没有重复,我们记录长度(和max比较),移动j。
set变为abc,还没有重复,我们记录长度(和max比较),移动j。
set变为abcc,在这里重复了,然后把i进行移动(把第i个字符在set里面去掉),
set变成bcc,在这里重复了,然后把i进行移动(把第i个字符在set里面去掉),
set变成cc,在这里重复了,然后把i进行移动(把第i个字符在set里面去掉),
set变成c,还没有重复,我们记录长度(和max比较),移动j。
set变成cd,还没有重复,我们记录长度(和max比较),移动j,发现到String的最尾部了,所以停止算法。
总结就是:
定义一个hashSet,
当(i和j没有到达尾部时):{
根据j的位置取出字符,存进char c;
如果c不存在set里面{
我们把存进set里面,记录长度,然后移动j的位置
}
如果c存在在set的位置{
我们移动i的位置(去掉hashSet的第i个元素,然后i++);
}
}
代码
public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Set<Character> set = new HashSet<>();
int i=0,j=0,num=0;
while(i<n && j<n){
char c=s.charAt(j);
//如果不包含c的话
if(!set.contains(c)){
num=Math.max(num,j-i+1);
set.add(s.charAt(j++));
}
else{
set.remove(s.charAt(i++));
}
}
return num;
}
}
滑动窗口的解法二:
import java.util.*;
public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
//在这里改为map比较好
Vector v = new Vector();
int i=0,j=0,num=0;
while(i<n && j<n){
char c=s.charAt(j);
//如果不包含c的话
if(v.indexOf(c)==-1){
num=Math.max(num,j-i+1);
v.addElement(s.charAt(j++));
}
else{
if(v.indexOf(c)!=-1){
v.removeElementAt(0);
i++;
}
}
}
return num;
}
}
完成。