1. 程式人生 >實用技巧 >其它 >2021-05-12

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倍

2021-05-12