Given a string, find the length of the longest substring without repeating characters.
Examples:
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.
题目的意思很好懂,关键是搞清楚子字符串与子字符序列的区别就行了,而且例子也给的很明确,所以对问题的理解应该没有很大的困难。
public class LongestSubstringWithoutRepeatingCharacters {
public int lengthOfLongestSubstring(String s) {
if (s.length() == 0)
return 0;
if (s.length() == 1)
return 1;
int longest = 1;
int i = 0, j = 1;
for (;i < j && j < s.length();){
String t = s.substring(i, j);
if (t.indexOf(s.charAt(j)) == -1){
if (j - i + 1 > longest)
longest = j - i + 1;
j++;
}else{
i = i + t.indexOf(s.charAt(j)) + 1;
j = i + 1;
}
}
return longest;
}
}
以上方法是最直接的想法,设置两个指针i,j,先截取一个[i,j)之间字符串,递增式地与下一个字符作比较,如果j指向的字符跟在当前字符串中不存在,那么将这个字符归入到这个字符串中,记录当前最大字符串,然后继续比较下一个字符是否在这个字符串中存在……如果这个字符在字符串中不存在,那么i就应该从j开始, 注意这里i的位置是绝对位置,j移动到下一个位置,继续做比较,以此类推……但是当我提交上OJ的时候,它告诉我在输入这样的一个超变态长度的字符串的时候竟然报了一个“Time Limit Exceeded”的错误,NND,看来这个算法的时间复杂度还是达不到人家的要求,实在没办法,继续改呗,绞尽脑汁也没想出啥办法,于是参考了 陈大师的想法有了下面的算法:
public class LongestSubstringWithoutRepeatingCharacters {
public int lengthOfLongestSubstring(String s) {
int[] charSet = new int[256];
for (int i = 0; i < charSet.length; i++){
charSet[i] = -1;
}
int longest = 0;
int lastRepeatPos = -1;
for (int i = 0; i < s.length(); i++){
if (charSet[s.charAt(i)] != -1 && lastRepeatPos < charSet[s.charAt(i)]){
lastRepeatPos = charSet[s.charAt(i)];
}
if (i - lastRepeatPos > longest) {
longest = i - lastRepeatPos;
}
charSet[s.charAt(i)] = i;
}
return longest;
}
}
该算法成功地通过了leetcode平台,虽然运行的速度排名不是很靠前。这个方法很巧妙地运用了ASCII码字符集,以每个字符对应的十进制数作为数组下标,数组存该字符在字符串中最新重复的位置。如果在扫描的过程中发现该字符有有冲突,那么记录当前位置为最近重复位置,然后再与当前最大长度作比较,最后得出结论……