1. 程式人生 > >LeetCode筆記3——無重複字元的最長子串

LeetCode筆記3——無重複字元的最長子串

題目:

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

示例 1:

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

示例 2:

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

示例 3:

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

思路1 暴力法:依次檢查字串中 的每一個字元,將其加入到Hashset中。如果不包含該字元就新增,並記錄set的大小;如果包含的話,就將set情空。

程式碼:

class Solution {     public int lengthOfLongestSubstring(String s) {        int N=s.length();         if(N==1)             return 1;        Set <Character>hashset=new HashSet<>();  //HashSet的建立         int j=0;         int max=0;         while(j<N)         {             int i=j+1;             hashset.add(s.charAt(j));             while(i<N)         {             Character tem=s.charAt(i);             if(!hashset.contains(tem))             {                 hashset.add(tem);                 i++;                 max=Math.max(max,hashset.size());             }             else             {                 max=Math.max(max,hashset.size());                 hashset.clear();                 //i++;                 break;   //這裡遇見相等的直接跳出內迴圈,i再加1 的話會出錯             }         }             j++;         }         return max;     } }

思路2:(以下均摘自leetcode解答)

優化的滑動視窗

上述的方法最多需要執行 2n 個步驟。事實上,它可以被進一步優化為僅需要 n 個步驟。我們可以定義字元到索引的對映,而不是使用集合來判斷一個字元是否存在。 當我們找到重複的字元時,我們可以立即跳過該視窗。

也就是說,如果 s[j]s[j]s[j] 在 [i,j)[i, j)[i,j) 範圍內有與 j′j'j​′​​ 重複的字元,我們不需要逐漸增加 iii 。 我們可以直接跳過 [i,j′]

範圍內的所有元素,並將 iii 變為 j′+1j' + 1j​′​​+1。

public class Solution {     public int lengthOfLongestSubstring(String s) {         int n = s.length(), ans = 0;         Map<Character, Integer> map = new HashMap<>(); // current index of character         // try to extend the range [i, j]         for (int j = 0, i = 0; j < n; j++) {             if (map.containsKey(s.charAt(j))) {                 i = Math.max(map.get(s.charAt(j)), i);             }             ans = Math.max(ans, j - i + 1);             map.put(s.charAt(j), j + 1);         }         return ans;     } }

思路3:

以前的我們都沒有對字串 s 所使用的字符集進行假設。

當我們知道該字符集比較小的時侯,我們可以用一個整數陣列作為直接訪問表來替換 Map

常用的表如下所示:

  • int [26] 用於字母 ‘a’ - ‘z’或 ‘A’ - ‘Z’
  • int [128] 用於ASCII碼
  • int [256] 用於擴充套件ASCII碼

public class Solution {     public int lengthOfLongestSubstring(String s) {         int n = s.length(), ans = 0;         int[] index = new int[128]; // current index of character         // try to extend the range [i, j]         for (int j = 0, i = 0; j < n; j++) {             i = Math.max(index[s.charAt(j)], i);             ans = Math.max(ans, j - i + 1);             index[s.charAt(j)] = j + 1;         }         return ans;     } }