題目
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,防止影響下一個第一層循環的數據
- 存入以前判斷Set中是否已經存在字符串
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)
,N
爲S
的長度
結果
- 執行用時:
99
ms, 在全部 Java 提交中擊敗了12.37
%的用戶 - 內存消耗:
38.7
MB, 在全部 Java 提交中擊敗了39.62
%的用戶
雙指針版本
解題思路
雙指針
,又名滑動窗口
,其實就是一個隊列
,好比例題中的 abcabcbb
,進入這個隊列(窗口)爲 abc
知足題目要求,當再進入 a,隊列變成了 abca,這時候不知足要求。因此,咱們要移動這個隊列!code
1,從A ->ABC
當前Left爲0,Right爲2,總體的結果最大長度爲3,緩存cache中已經有了數據{A:0,B:1,C:2}
索引
2. ABCA
當再次遇到A
時,緩存cache
中已經存在了A
字符串,咱們須要比較【當前A
在緩存中的位置】,與【當前Left
的值】,若是Left
的值小於等於A
在緩存中的位置,那麼咱們須要調整Left
的值爲(A
在緩存中的位置 + 1
),這麼作主要是爲了Left座標始終處於最新的重合點的位置的後面一位
,組成新的不重合的長度
- 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