LeetCode3:Longest Substring Without Repeating Characters(無重複字元的最長子串)

gengzhibo發表於2019-01-11

LeetCode3:Longest Substring Without Repeating Characters(無重複字元的最長子串)

歡迎訪問我的部落格

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

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

題目說明

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

示例

  • 示例 1:
    • 輸入: "abcabcbb"
    • 輸出: 3
    • 解釋: 因為無重複字元的最長子串是 "abc",所以其長度為 3。
  • 示例 2:

    • 輸入: "bbbbb"
    • 輸出: 1
    • 解釋: 因為無重複字元的最長子串是 "b",所以其長度為 1。
  • 示例 3:

    • 輸入: "pwwkew"
    • 輸出: 3
    • 解釋: 因為無重複字元的最長子串是 "wke",所以其長度為 3。 請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。

解題方法

日常暴力法

遍歷每個元素作為一個字串開始,查詢當前字串是否元素不重複,如果不重複則得到其長度,全部遍歷得到其最長無重複自串長度.

滑動視窗(HaskMap輔助表)

HaskMap真是個好東西,最近再整理下HashMap相關的資料

此方法只需要一次遍歷即可,主要思路為在遍歷過程中計算當前遍歷位置到最後一個重複元素的下一位位置的長度(也可以說是將最後一次重複的元素的下一位作為一個子串的開始,當前遍歷位置作為子串的結束,計算此子串的長度),將其與已存在的最長子串長度對比,得到當前最長未重複元素子串的長度.下面通過圖示解析相關思路.

圖解相關思路

我們輸入"pwwkew"作為引數,此時預設最長無重複子串長度(result)為0,HashMap輔助表check為空.

輸入條件

預設遍歷位置i = 0, 預設最後一個重複元素的下一位位置index = 0;

查詢輔助表check中不存在i位置對應的元素p

當前最長無重複元素子串長度result = i(0) - index(0) + 1 = 1

更新check表,將(p,0)加入到check表中

i=0

繼續遍歷此串,當i = 1時,check中依舊查詢不到i位置對應的元素w

result = i(1) - index(0) + 1 = 2

更新check表,將(w,1)加入到check表中

i=1

繼續遍歷當i = 2時,此時i對應的元素w在check表中可以被找到,說明此元素是一個重複元素,我們需要更新index的值,在這裡我們比較當前index的值和check中出現的最後一次重複元素的下一位中的較大值(防止"abba"這樣的在遍歷最後一個a的時候取到首位a的位置).

i=2(0)

此時index = max(index(0), check.get(key("w")) (1 + 1 = 2)) = 2

計算當前的result = i(2) - index(2) + 1 = 1,小於之前的result(2),此時result依然為2.

更新check表的內容,將key為w的value更改為2

i=2(1)

繼續遍歷,當i = 3時,check表中找不到'k'

result = i(3) - index(2) + 1 = 2

更新check表,將(k,3)加入到check表中

i=3

繼續遍歷,當i = 4時,check表中找不到'e'

result = i(4) - index(2) + 1 = 3, 此時的result大於原有的result,則更新result的值為3

更新check表,將(e,4)加入到check表中

i=4

繼續遍歷當i = 5時,此時i對應的元素w在check表中可以被找到,

i=5(0)

此時index = max(index(5), check.get(key("w")) (2 + 1 = 3)) = 5

計算當前的result = i(5) - index(2) + 1 = 3,大於之前的result(2),此時result更新為3.

更新check表的內容,將key為w的value更改為5

i=5(1)

至此,遍歷結束,此時reslut的值就是s中最長為重複子串的長度.

程式碼實現

public int lengthOfLongestSubstring(String s) {
    int result = 0;
    Map<Character, Integer> check = new HashMap<>();
    for (int i = 0, index = 0; i < s.length(); i++) {
        if (check.containsKey(s.charAt(i))){
            index = Math.max(index, check.get(s.charAt(i)) + 1);
        }
        result = Math.max(result, i - index + 1);
        check.put(s.charAt(i), i);
    }

    return result;
}
複製程式碼

相關程式碼歡迎大家關注並提出改進的建議

相關文章