1. 程式人生 > >無重複字元的最長子串(佇列,滑動視窗)

無重複字元的最長子串(佇列,滑動視窗)

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

示例 1:

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

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

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

思路:給定一個佇列,新增計數,檢測是否有重複的key,重複則出列,直到key出列,然後key進佇列計算count=size

若無重複則count++

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if (s.equals("")) {
            return 0;
        }
        int count = 1;
        int max=1;
        Queue<Character> list = new LinkedList<Character>();
        list.offer(s.charAt(0));
        for (int i = 1; i < s.length(); i++) {
            if (list.contains(s.charAt(i))) {
                do {
                    list.poll();
                } while (list.contains(s.charAt(i)));
                list.offer(s.charAt(i));
                count = list.size();
            } else {
                ++count;
                list.offer(s.charAt(i));
            }

            if (max < count) {
                max = count;
            }
        }
        return max;
}}

其中佇列可以替換為為hashset,同理.,兩個指標,一個表示當前,一個表示刪除指標,刪除一直進行到不包含當前char為止

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        Set<Character> set = new HashSet<>();
        int ans = 0, i = 0, j = 0;
        while (i < n && j < n) {
            // try to extend the range [i, j]
            if (!set.contains(s.charAt(j))){
                set.add(s.charAt(j++));
                ans = Math.max(ans, j - i);
            }
            else {
                set.remove(s.charAt(i++));
            }
        }
        return ans;
}}

還可以繼續優化,這裡時間複雜度為2n

可以繼續優化為n,使用map,key為char,value記錄當前char的下標,當發現重複的時候 j 直接跳到

Max(重複的地方+1 ,j)//防止abcba 出現 j變小的現象  ,j只會線性增加

class Solution {
    public int lengthOfLongestSubstring(String s) {
        HashMap<Character,Integer> map = new HashMap<>();
        int j=0,ans=0;
        for(int i=0;i<s.length();i++){
            if(map.containsKey(s.charAt(i))){
                j =Math.max(map.get(s.charAt(i))+1,j) ;
            }
            ans = Math.max(ans,i-j+1);
            map.put(s.charAt(i),i);
        }
        return ans;
}}

這裡map可以還可以優化為陣列 int[] a = new int[];

  • int [26] 用於字母 ‘a’ - ‘z’或 ‘A’ - ‘Z’
  • int [128] 用於ASCII碼
  • int [256] 用於擴充套件ASCII碼
  • index[s.charAt(i)] = i;