原题:https://leetcode.com/problems/longest-substring-without-repeating-characters/?tab=Description
找到没有重复的最长子串(substring)。比如pwwkew
结果就是wke
。这题乍一看上去这样想,双重循环,外层从头开始扫描,读取一个字母就在已经读到的子串里找有没有重复的,有就返回。然后把最长的记录下来。这个brute force我写了半天没写出来。。
好的方法是窗口法。维护两个窗口,一个在前面走一个在后面走,runner先走,走一步就检查一下现有的hashSet里面有没有当前的位置的char(contains
的复杂度是O(1),只有在hash冲突的时候才会稍微遍历一下子,具体看之前我发的effective java里的hashmap原理),set里没有就继续右移,有的话,walker开始右移,移动到跟runner指向的char不同为止。
窗口法是string类型题目常有的套路。
已犯错误:
- walker移动到跟runner相同之后runner没有右移一位。
- return的应该是Math.max(maxLen,runner-walker);
public int lengthOfLongestSubstring(String s) {
if (s.length() == 0) return 0;
int runner = 0, walker = 0;
int maxLen = 0;
HashSet<Character> set = new HashSet<>();
while (runner < s.length()) {
if (!set.contains(s.charAt(runner))) {
set.add(s.charAt(runner));
runner++;
} else {
if (runner - walker > maxLen) maxLen = runner - walker;
while (s.charAt(runner) != s.charAt(walker)) {
set.remove(s.charAt(walker));
walker++;
}
// 分别再走一步
walker++;
runner++;
}
}
return Math.max(maxLen,runner-walker);
}
还有一种奇淫巧技是利用char的value当做index,然后hash:
http://blog.csdn.net/likecool21/article/details/10858799
reference:
http://blog.csdn.net/linhuanmars/article/details/19949159