這是個人第一篇博文,建立這個分類是由於我的比較喜歡研究算法,Ok,Talk is cheap,Let's go,I will show you my code.算法
題目描述以下:spa
給定一個字符串,請你找出其中不含有重複字符的 最長子串 的長度。code
示例 1:blog
輸入: "abcabcbb" 輸出: 3 解釋: 由於無重複字符的最長子串是 長度爲 3。"abc",因此其
示例 2:rem
輸入: "bbbbb" 輸出: 1 解釋: 由於無重複字符的最長子串是 ,因此其長度爲 1。 "b"
示例 3:字符串
輸入: "pwwkew" 輸出: 3 解釋: 由於無重複字符的最長子串是 ,因此其長度爲 3。 請注意,你的答案必須是 子串 的長度, 是一個子序列,不是子串。"wke""pwke"
咱們來分析一下這個問題,要想找到給定字符串的無重複字符的最長字串的長度,那要對字符串進行遍歷,第一種思路是:遍歷字符串中的全部字符,並把它們存入set集合中,在存入以前先判斷set中是否已經
包含該元素,若包含則返回true,不然返回false,並存入set中。下面咱們看下代碼:
1 /** 2 * 3 * @param s 輸入的字符串 4 * @return 最長不重複字串的長度 5 */ 6 public int lengthOfLongestSubstring(String s) { 7 int length = s.length();//取得字符串的長度 8 int size = 0; 9 for (int i = 0; i < length; i++) { 10 for (int j = i + 1; j <= length; j++) { 11 if (!isReapt(s, i, j)) { 12 size = Math.max(size, j - i); 13 } 14 } 15 } 16 17 return size; 18 } 19 20 /** 21 * 22 * @param s 輸入的字符串 23 * @param front 指向字符串的頭部 24 * @param rear 指向字符串的尾部 25 * @return 若重複則返回true,不然返回false 26 */ 27 public boolean isReapt(String s, int front, int rear) { 28 Set<Character> set = new HashSet(); 29 for (int i = front; i < rear; i++) { 30 Character c = s.charAt(i); 31 if (set.contains(c)) { 32 return true; 33 } 34 set.add(c); 35 } 36 return false; 37 }
上面那種解法雖然能解決問題,但過於笨重,那有沒有一種辦法能夠更快呢?答案是有的。咱們用到滑塊的思想。代碼以下:
1 /** 2 * 3 * @param s 傳入的字符串 4 * @return 最長不重複字串的長度 5 */ 6 public int lengthOfLongestSubstring(String s) { 7 int length = s.length();//取得輸入字符串的長度 8 Set<Character> set = new HashSet<>(); 9 int size = 0; 10 int front = 0;//滑塊頭 11 int rear = 0;//滑塊尾 12 while (front < length && rear < length) { 13 14 if (!set.contains(s.charAt(rear))){//若是set中不包含當前元素,就把它添加到set中,並更新ans值 15 16 set.add(s.charAt(rear++)); 17 size = Math.max(size, rear - front); 18 19 } 20 else { 21 22 set.remove(s.charAt(front++));//若是set中包含當前元素,就經過逐一移動i的方式刪除set內的元素, 23 //直到set.contains(s.charAt(j))條件不知足爲止 24 } 25 } 26 return size; 27 }