无重复字符的最长子串 leetcode第三题
首先明确一点,可以直接用set结构判重,那么最简单的方案就是直接暴力破解,双层循环,里层直接循环计算最长子串
// 暴力破解方案
public static int lengthOfLongestSubstring(String s) {
Set<Character> set = new HashSet();
int maxSize = 0;
for (int i = 0; i < s.length(); i++) {
for (int j = i; j < s.length(); j++) {
boolean notRepeat = set.add(s.charAt(j));
if (!notRepeat) {
maxSize = set.size() > maxSize ? set.size() : maxSize;
set.clear();
break;
}
}
// 每一轮循环完都清一次
maxSize = set.size() > maxSize ? set.size() : maxSize;
// 最大值就不在轮循了
if (maxSize == s.length()) {
return maxSize;
}
set.clear();
}
return maxSize;
}
这个方案易于理解,但是明显内层会有很多重复的循环,会重复判断已经存在过的最长不重复子串。那么这里引入时间窗概念,可自行搜索相关概念。
// 时间窗解法
public static int lengthOfLongestSubstringByWindow(String s) {
Set<Character> set = new HashSet();
int maxSize = 0;
for (int i = 0; i < s.length(); i++) {
// 移除掉当前这轮左边的一个
set.remove(s.charAt(i - 1 < 0 ? i : i - 1));
// 找到当前这轮的最大序列,注意第二轮开始set里已经有当前窗口的值了,只需要从最远节点开始继续放就行
for (int j = set.size() + i; j < s.length(); j++) {
boolean noRepeat = set.add(s.charAt(j));
if (!noRepeat) {
maxSize = set.size() > maxSize ? set.size() : maxSize;
break;
}
}
// 有可能一轮循环到完都没有重复的
maxSize = set.size() > maxSize ? set.size() : maxSize;
// 全是不重复的就不在轮循了
if (maxSize == s.length()) {
return maxSize;
}
}
return maxSize;
}