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;
}
}
完成。