2021-05-12
##菜鳥刷題(1)【無重複字元的最長子串】
力扣 3.無重複字元的最長子串
給定一個字串,請你找出其中不含有重複字元的最長子串的長度。
示例1:
輸入:s="abcabcbb"
輸出:3
解釋:因為無重複字元的最長子串是"abc",所以其長度為3。
示例2:
輸入:s="bbbbb"
輸出:1
解釋:因為無重複字元的最長子串是"b",所以其長度為1。
示例3:
輸入:s="pwwkew"
輸出:3
解釋:因為無重複字元的最長子串是"wke",所以其長度為3。
請注意,你的答案必須是子串的長度,"pwke"是一個子序列,不是子串。
示例4:
輸入:s=""
輸出:0
程式碼:
classSolution{
publicintlengthOfLongestSubstring(Strings){
Mapmap=newHashMap();
intleft=0;
intmax=0;
for(inti=0;i<s.length();i++){
if(map.containsKey(s.charAt(i))){
left=Math.max((Integer)map.get(s.charAt(i))+1,left);
}
map.put(s.charAt(i),i);
max=Math.max(max,i-left+1);
}
returnmax;
}
}
用到的是滑動視窗
思路:
例如"abcab",先找到不重複的字串abc,再看下一位即abca,a與前面的重複,把第一個a去掉則字串變為bca,然後再看下一位bcab,b重複,把第一個b去掉,變為cab。因為題目是求長度,而不是具體的字串,所以這個思路是沒問題的
程式碼說明:
left用於指示最長不重複字串的第一個字元下標
i用於指示最長不重複字串的最後一個字元下標
max最長不重複字串的長度max=i-left+1
遍歷字串s中的每一個字元,判斷map中是否含有與當前字元重複的
{如果沒有,將該字元放入map,字元為key,下標為value。計算max,max=Math.max(max,i-left+1),這個好理解就是之前的max值和現在計算的長度取最大值},
{如果有,則移動left,left=Math.max((Integer)map.get(s.charAt(i))+1,left),這裡為什麼也要用個函式取最大值?考慮例子"abba",如果不取最大值,ab之後,abb時,第三個字元b與map中的b重複,left指向第一個b的下一位,變為2(下標),再看下一字元,即第四個字元a,也是與map中的a重複,left指向第一個a的下一位,變為1,最終max=i-left+1=3,就是bba的長度,錯的。。所以left這裡必須要取最大值}
再貼一個一般第一眼想到的方法,就是找所有不同子串,判斷長度
public static void repeatChar(String s) {
String a="";
int flag=0;
int max=0;
for(int i=0;i<s.length();i++){
for(int j=i;j<s.length();j++){
for (int k = 0; k < a.length(); k++) {//判斷s的當前字元是否有與a字串中重複的
if (a.charAt(k) == s.charAt(j)) {
flag = 1;
break;
}
}
if(flag==1){//有重複
max=Math.max(max,a.length());//記錄長度
a="";//重置a,為下一個不同字串做準備
flag=0;//重置flag
break;//終止第二層迴圈
}else{//無重複,繼續拼接
a += s.charAt(j);
}
max=Math.max(max,a.length());
}
}
System.out.println(max);
}
當然這種方法的時間複雜度就噌噌噌的漲了,兩個方法執行時間差距超過100倍

