LeetCode每日一題,無重複字符的最長子串

題目

https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/java

無重複字符的最長子串

公衆號 《java編程手記》記錄JAVA學習平常,分享學習路上點點滴滴,從入門到放棄,歡迎關注編程

描述

給定一個字符串,請你找出其中不含有重複字符的 最長子串 的長度。緩存

示例 1:ide

輸入: s = "abcabcbb"
輸出: 3 
解釋: 由於無重複字符的最長子串是 "abc",因此其長度爲 3

示例 2:學習

輸入: s = "bbbbb"
輸出: 1
解釋: 由於無重複字符的最長子串是 "b",因此其長度爲 1。

示例 3:url

輸入: s = "pwwkew"
輸出: 3
解釋: 由於無重複字符的最長子串是 "wke",因此其長度爲 3。
  請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。

示例 4:.net

輸入: s = ""
輸出: 0
0 <= s.length <= 5 * 104
s 由英文字母、數字、符號和空格組成

Solution

解法

暴力思路

檢查重複字符串的思路有哪些?指針

  • 兩次遍歷循環字符串
    • 第一層循環記錄頭部信息
    • 第二層循環用來滑動數據
    • 將第二層數據存入到Set
      • 存入以前判斷Set中是否已經存在字符串
        • 有則BREAK,進入下一個外層循環
      • 計算最新的結果長度,而且將當前字符串存入到Set
      • 每當第二次循環完成以後,清空Set,防止影響下一個第一層循環的數據

image-20210412233857464

CODE

class Solution {
     public int lengthOfLongestSubstring(String s) {
       int res = 0 ;
       Set<Character> set = new HashSet<>();
       for(int i = 0 ; i < s.length();i++){
           for(int j = i ; j < s.length() ; j++){
               if(set.contains(s.charAt(j))){
                  break;
               }
               if(j-i+1 > res){
                   res = j-i+1;
               }
               set.add(s.charAt(j));
           }
           set.clear();
       }
       return res;
    }
}

複雜度

  • 時間複雜度:O(N^2)NS的長度

結果

  • 執行用時:99 ms, 在全部 Java 提交中擊敗了12.37%的用戶
  • 內存消耗:38.7 MB, 在全部 Java 提交中擊敗了39.62%的用戶

雙指針版本

解題思路

雙指針,又名滑動窗口,其實就是一個隊列,好比例題中的 abcabcbb,進入這個隊列(窗口)爲 abc 知足題目要求,當再進入 a,隊列變成了 abca,這時候不知足要求。因此,咱們要移動這個隊列!code

image-20210413223133481

1,從A ->ABC

當前Left爲0,Right爲2,總體的結果最大長度爲3,緩存cache中已經有了數據{A:0,B:1,C:2}索引

image-20210413224027748

2. ABCA

當再次遇到A時,緩存cache中已經存在了A字符串,咱們須要比較【當前A在緩存中的位置】,與【當前Left的值】,若是Left的值小於等於A在緩存中的位置,那麼咱們須要調整Left的值爲(A在緩存中的位置 + 1),這麼作主要是爲了Left座標始終處於最新的重合點的位置的後面一位,組成新的不重合的長度

image-20210413231002777

  1. ABCAB

跟上面同理,當遇到B時,緩存中已經存在了B字符串,須要比較【當前B在緩存中的位置】,與【當前Left的值】,若是Left的值小於等於``B在緩存中的位置,那麼久須要調整Left的值爲(B在緩存中的位置+1),最終是爲了Left座標始終處於最新的重合點(B)的位置的後面一位,組成新的不重合的長度

CODE

class Solution {
     public int lengthOfLongestSubstring(String s) {
         
       int length = s.length();
       if(length == 0){
           return 0;
       }
       int res = 0 ;
       //快指針
       int right = 0 ;
       //慢指針 
       int left = 0 ;
       //索引,空間換時間
       Map<Character,Integer> map = new HashMap<>();
       for(;right<length;right++){
           Character c = s.charAt(right);
        if(map.containsKey(c)){
            //更新left
            if( map.get(c) >= left){
                    left = map.get(c)+1;
            }
        }
        //更新結果res
        if((right-left+1)>res){
                res = (right-left+1);
        }
         //更新c的位置
        map.put(c,right);

       }
       return res ;
    }
}

複雜度

  • 時間複雜度:O(N)N爲字符串長度

結果

  • 執行用時:7 ms, 在全部 Java 提交中擊敗了79.24%的用戶

  • 內存消耗:38.8 MB, 在全部 Java 提交中擊敗了28.63%的用戶

參考

https://www.bilibili.com/video/BV1St4y1k72y?from=search&seid=12825150742902127069

https://www.bilibili.com/video/BV1r7411X7mJ?from=search&seid=15075195474456497360

相關文章
相關標籤/搜索