标签:
题目:给定一个字符串string,找出string中无重复字符的最长子串。
举例:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, the answer is "wke"
, with the length of 3. Note that the answer must be asubstring, "pwke"
is a subsequence and not a substring.
思路:
首先,因为找的是无重复的子串,因此我们使用Hashset结构来存放已经找到的字符,HashSet中保存的是从某个位置pre到另一个位置i中间的所有字符。
从头开始遍历给定的字符串s, 每遍历一个,判断HashSet中是否有该字符,假设此时遍历到i位置:
1: 如果没有,就将字符加入HashSet, 表明子串的长度又增大了一个,即prev~i位置的字符串是无重复字符的,更新最长字串的长度max_str;
2: 如果有,就从prev位置开始循环遍历,直到找到与i位置字符相等的那个字符,然后prev指向那个字符位置+1的位置,i继续遍历。
直到i==len结束遍历。但此时还应该计算一次Max(i-prev, max_str)的大小,最后一次更新max_str的大小,返回最终的max_str;
扩展:
假设本题要求找出无重复的最长子串,则需要用两个变量保存窗口的左右位置,每当max_str更新的时候,就需要更新此时的窗口左右位置。最终使用s.substring(left, right)获取最长子串。
本题代码:
1 public class Solution { 2 public int lengthOfLongestSubstring(String s) { 3 if(s == null || s.length() < 1) 4 return 0; 5 HashSet<Character> set = new HashSet<Character>(); 6 int pre = 0; // 窗口的左边界 7 int max_str = Integer.MIN_VALUE; // 最长字串长度 8 int i = 0; // 窗口的右边界 9 int len = s.length(); 10 while(i < len) 11 { 12 if(set.contains(s.charAt(i))) // 找到与i位置相等的那个字符,pre指向该字符的下一个位置,重新开始窗口 13 { 14 if(i - pre > max_str) 15 max_str = i - pre; 16 while(s.charAt(pre) != s.charAt(i)) //直到找到与当前字符相等的那个字符,然后才可以重新开始新一轮的窗口计数 17 { 18 set.remove(s.charAt(pre)); 19 pre ++; 20 } 21 pre ++; 22 } 23 else 24 { 25 set.add(s.charAt(i)); 26 } 27 i++; 28 } 29 max_str = Math.max(max_str, i - pre); // i一直向后,直到超出s的长度,此时也要计算窗口的大小 30 return max_str; 31 32 } 33 }
标签:
原文地址:http://www.cnblogs.com/leavescy/p/5877109.html