LeetCode之無重復字符的最長子串超詳細java講解


描述:給定一個字符串,請你找出其中不含有重復字符的 最長子串 的長度。

輸入: s = "abcabcbb"
輸出:3 解釋: 因為無重復字符的最長子串是 "abc",所以其長度為 3。

輸入: s = "bbbbb"輸出: 1
解釋: 因為無重復字符的最長子串是"b",所以其長度為1.

=================================================================
思路一:暴力求解,依次從左往右,遇到相同的就直接結束,然后從后面一個字符開始,
最后的出最長子串。

    {(a)bcabcbb}(a)bcabcbb 開始的最長字符串為 {(abc)abcbb}(abc)abcbb;
    {a(b)cabcbb}a(b)cabcbb 開始的最長字符串為 {a(bca)bcbb}a(bca)bcbb;
    {ab(c)abcbb}ab(c)abcbb 開始的最長字符串為 {ab(cab)cbb}ab(cab)cbb;
    {abc(a)bcbb}abc(a)bcbb 開始的最長字符串為 {abc(abc)bb}abc(abc)bb;
    {abca(b)cbb}abca(b)cbb 開始的最長字符串為 {abca(bc)bb}abca(bc)bb;
    {abcab(c)bb}abcab(c)bb 開始的最長字符串為 {abcab(cb)b}abcab(cb)b;
    {abcabc(b)b}abcabc(b)b 開始的最長字符串為 {abcabc(b)b}abcabc(b)b;
    {abcabcb(b)}abcabcb(b) 開始的最長字符串為 {abcabcb(b)}abcabcb(b)。

 完整代碼如下:

public int lengthOfLongestSubstring(String s){ int max = 0; HashMap<Character,Integer> map = new HashMap<>(); for(int i = 0;i<s.length();i++){ int cur = 0;   //每次都要清零整個HashMap表
 map.clear(); for(int j = i;j<s.length();j++){ if(map.containsKey(s.charAt(j))){   //遇到相同的則直接跳出循環
                    break; } map.put(s.charAt(j),j); cur++; } max = Math.max(max,cur); } return max; }

 

 
        
=================================================================
思路二:利用滑動窗口:類似於一個隊列,比如例題中的 abcav,進入這個窗口為 abc
滿足題目要求,當再進入 a隊列變成了 abca,這時候不滿足要求。所以,我們
要移動這個隊列,此時的窗口值為bca即left移動到,b位置,移動到重復值a的后
一位。相當於將與當前相同的值的左邊全部移出窗口.
時間復雜度:O(n)
===========================================================================
什么是滑動窗口
滑動窗口算法是在一個特定大小的字符串或數組上進行操作,而不在整個
字符串和數組上操作,這就降低了問題的復雜度,從而也降低了循環的嵌套深度,
滑動窗口主要應用在數組和字符串的場景。
================================================================================
滑動窗口的基本步驟:
需要注意的是:窗口的移動是按照移動的順序來進行的;窗口的大小不一定是固
定的,可以不斷縮小或變大的。

 對於滑動窗口算法的基本解題思路,以字符串S示例如下:

 1.采用雙指針來指定窗口的范圍,初始化left= right=0,而索引閉區間[left,right]

  便是一個窗口。

 2.不斷增大窗口的right指針,直到窗口的字符串滿足要求。

 3.此時停止right的增加,轉而不斷增加left指針,用於縮小窗口[left,right],直到窗

  口中的字符串不在滿足要求。每增加一次left,需要更新一次結果。

 4. 重復第2和第3步,直到right到達字符串的盡頭。

==============================================================================
完整代碼如下:
public int lengthOfLongestSubstring(String s){
        HashMap<Character,Integer> map = new HashMap<>();
        int max = 0;   //最長長度
        int left = 0;  //滑動窗口最初為零
        for(int i = 0;i<s.length();i++){
            if(map.containsKey(s.charAt(i))){      //如果包含,則更新left,
                left = Math.max(left,map.get(s.charAt(i)+1)); //之所以要不能直接取map.get(s.charAt(i))+1是因為當前值可能不包含在有效字段里面
            }
            map.put(s.charAt(i),i);//更新left后,不管原來的 s.charAt(i) 是否在最長子段中,我們都要將 s.charAt(i) 的位置更新為當前的i,
            //如果包含了,則會把之前的給覆蓋掉。
            max = Math.max(max,i-left+1);  //更新max
        }
        return max;
    }

 

 

 2021-05-29


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM