1. 程式人生 > >Longest Substring Without Repeating Characters---LeetCode進階路③

Longest Substring Without Repeating Characters---LeetCode進階路③

  • 題目描述

Given a string, find the length of the longest substring without repeating characters.

Example 1:

Input: "abcabcbb"
Output: 3 
Explanation: The answer is "abc", with the length of 3. 

Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3. 
             Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
  • 思路分析

輸出最大無重複字元的子字串長度,很常規的資料結構題目。

最粗暴的BF演算法就可以解決,當然時間複雜度會是O(n^2)這樣的鬧心樣子。

小陌想到的方法是,建立陣列儲存字串,從頭開始捋,遇到重複的字元則從下一個元素開始下一輪的子字串尋找,即每個子字串從相應起點開始到下一個有重複字元位置。

小陌特別想分享下被圈粉的大神思路 :用HashSet維護當前字串,左右兩端一起搞。

例如我們從左邊先開始,只要沒有出現重複字元就繼續左移;一旦出現重複字元,就換一條路,從右邊開始。中間所忽略的那些,它們是有重複或者更短,值得“忽略”。而在左右開弓的情況下,至多對元素訪問一遍,時間複雜度僅為O(n)。

大神的思路闡述:“基本思路是維護一個視窗,每次關注視窗中的字串,在每次判斷中,左視窗和右視窗選擇其一向前移動。同樣是維護一個HashSet, 正常情況下移動右視窗,如果沒有出現重複則繼續移動右視窗,如果發現重複字元,則說明當前視窗中的串已經不滿足要求,繼續移動有視窗不可能得到更好的結果,此時移動左視窗,直到不再有重複字元為止,中間跳過的這些串中不會有更好的結果,因為他們不是重複就是更短。”

  • 原始碼附錄:

1.小陌的方法

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s == null || s.length() == 0){
            return 0;
        }
        
        int[] count = new int[256];
        int start = 0;
        int end = 1;
        int longest = 1;
        
        Arrays.fill(count,-1);
        count[s.charAt(0)] = 0;
        
        while(end < s.length()){
            if(count[s.charAt(end)] >= start){
                start = count[s.charAt(end)] + 1;
            }
            
            longest = Math.max(longest,end - start + 1);
            count[s.charAt(end)] = end;
            end ++;
        }
        
        return longest;
    }
}

 

2.大神的方法 (大神地址https://blog.csdn.net/linhuanmars/article/details/19949159

  class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s == null || s.length() == 0){
            return 0;
        }
        
        HashSet<Character> hs = new HashSet<Character>();
        int start = 0;
        int end = 0;
        int longest = 0;
        
        while(end < s.length()){
            if(hs.contains(s.charAt(end))){
                longest = Math.max(longest,end - start);
                while(s.charAt(start) != s.charAt(end)){
                    hs.remove(s.charAt(start));
                    start ++;
                }
                start ++;
            }
            else{
                hs.add(s.charAt(end));
            }
            
            end ++;
        }

        longest = Math.max(longest,end - start);
        return longest;
    }
  }