Longest Substring Without Repeating Characters - 哈希與雙指針

題意很簡單,就是尋找一個字符串中連續的最長包含不同字母的子串。

其實用最樸素的方法,從當前字符開始尋找,找到以當前字符開頭的最長子串。這個方法猛一看是個n方的算法,但是要注意到由於字符數目的限制,其實這是個O(Cn)的算法,最長也不過是C長度。所以我覺得普通方法應該是能過的。

於是寫了一個,字符數目最大也不超過256所以代碼如下:

 1 class Solution {
 2 public:
 3     int lengthOfLongestSubstring(string s) {
 4 
 5         int res=0;
 6         for(int i=0;i<s.length();i++)
 7         {
 8             int flag[200];
 9             memset(flag,0,sizeof(flag));
10             int count = 0;
11             flag[s[i]-' '] = 1;
12             int tempres = 1;
13             for (int j = i + 1; j < s.length(); j++) {
14                 if (flag[s[j]-' ']==0) {
15                     flag[s[j]-' ']= 1;
16                     tempres++;
17                 } else
18                     break;
19             }
20             if (tempres > res)
21                 res=tempres;
22         }
23         return res;
24     }
25 };

其中空格是ASCII碼第一個實際意義字符,所以減去‘ ’

正常的O(n)方法是使用哈希表來存已經出現的字符,使用一個指針依次檢索,如果碰到已經存在的字符,則去使用第二個指針更新這個哈希表。

從原理上來具體討論雙指針這個算法,對於第一個指針指到的字母有兩種情況:

1.從來沒有使用過

當前長度加一,將這個位置和字母加入哈希表,第二個指針不動

2.已經使用過,並且有一個哈希表存這個字母的上一個位置

獲取上一個位置右側位置(+1操作),將這個位置和第二個指針比較,

(1)如果小於第二個指針,說明以當前結尾的字符串在第j個指針的地方有字母重複,忽略這個位置,繼續以j爲準

(2)如果大於第二個指針,說明以當前結尾的字符串在這個最新的位置有重複,將指針移到這個位置,計算這個長度。

這三種情況涵蓋了所有可能,並在下面的例子中有相應出現。

代碼:

此代碼來自最多discuss區最多vote的答案:https://leetcode.com/discuss/23883/11-line-simple-java-solution-o-n-with-explanation

 1 public int lengthOfLongestSubstring(String s) {
 2         if (s.length()==0) return 0;
 3         HashMap<Character, Integer> map = new HashMap<Character, Integer>();
 4         int max=0;
 5         for (int i=0, j=0; i<s.length(); ++i){
 6             if (map.containsKey(s.charAt(i))){
 7                 j = Math.max(j,map.get(s.charAt(i))+1);
 8             }
 9             map.put(s.charAt(i),i);
10             max = Math.max(max,i-j+1);
11         }
12         return max;
13     }

例子:

對於這個字符串:abcbcda

經過初始化循環執行過程如下:

i=0;  j=0;  (a,0)  max(0,1)=1  第一種情況

i=1;  j=0;  (b,1)  max(1,2)=2  同上

i=2;  j=0;  (c,2)  max(2,3)=3  同上

i=3;  j=(0,1+1)=2;  (b,3)  max(3,2)=3  第二種第二個情況

i=4;  j=(2,2+1)=3;  (c,4)  max(3,2)=3  同上

i=5;  j=3;  (d,5)  max(3,3)=3  第一種情況

i=6;  j=(3,1)=3;   (a,6)  max(3,4)=4  第二種第一個情況

 

 

     

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章