3. 無重複字元的最長子串(LeetCode)
阿新 • • 發佈:2021-07-08
題目描述
給定一個字串 s ,請你找出其中不含有重複字元的最長子串的長度。
示例1:
輸入: s = "abcabcbb"
輸出: 3
解釋: 因為無重複字元的最長子串是 "abc",所以其長度為 3。
條件分析
- 字元無重複;
- 子串有連續的字元構成
解題思路(滑動視窗)
- 將字串拆分為字元陣列,定義一個變數maxLen儲存最長子串的長度;
- 定義兩個下標left,right,如果沒有重複,取maxLen為當前長度與maxLen的最大值,如果發現right和已有字元重複,則left=重複字元下標+1,right++,直到right到達末尾;
- 如何判斷字元在陣列中已經出現?可以考慮用一個數組freq將每個字元出現的下標記錄下來,值-1代表未出現,否則儲存的是元素的下標。注意在重置left的時候,老的left和新的left之間的freq元素也進行更新為-1,表示不再存在
編碼如下
public int lengthOfLongestSubstring(String s) { char[] cs = s.toCharArray(); int left = 0; // [left,right]為最大不重複子串 int right = -1; int maxLen = 0; int[] freq = new int[256]; // 儲存元素的下標,初始情況下所有元素都不存在 for (int i=0; i<freq.length; i++) { freq[i] = -1; } while (right < cs.length-1) { right++; // 元素不存在,計算最大值 if (freq[cs[right]] == -1) { maxLen = max(maxLen, (right - left + 1)); } else { // 元素存在,取出存在元素的下標+1,也就是left要移動到的新位置 int newLeft = freq[cs[right]] + 1; // 把老的left和新的left之間的元素都設定為不存在,相當於重置 while (left < newLeft) { freq[cs[left++]] = -1; } left = newLeft; } freq[cs[right]] = right; } return maxLen; } private int max(int max, int newMax) { if (newMax > max) { max = newMax; } return max; }