LeetCode第3題---無重複字符的最長子串

                     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;
        }
}

 

完成。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章