题目
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串的长度。
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
题解
方式一:双指针 + 滑动窗口(不固定)
复杂度:O(n) + substring
public int lengthOfLongestSubstring(String s) {
// 参数校验
if (s == null) return 0;
if (s.length() < 2) return s.length();
int ans = 0;
int l = 0; // 左指针
int r = 1; // 右指针
for (; r <= s.length(); r++) {
String sub = s.substring(l, r); // 窗口
ans = Math.max(ans, sub.length());
if (r < s.length()) {
// 当加上当前数据不符合要求时,移动左指针直到符合要求
char cur = s.charAt(r);
while (sub.indexOf(cur) != -1) {
l++;
sub = s.substring(l, r);
}
}
}
return ans;
}
方式二:集合
public int lengthOfLongestSubstring(String s) {
int ans = 0;
List<Character> list = new ArrayList<>(); // 窗口,保证有序不能用Set
for (char c: s.toCharArray()) {
if (list.contains(c)) {
// 不符合条件时,移除窗口数据直到符合条件
ans = Math.max(ans, list.size()); // 记录当前最长子串长度
Iterator<Character> iterator = list.iterator();
// 也可以记录左边界,remove(object),这里用迭代器按顺序移除
while (iterator.hasNext()) {
char cc = iterator.next();
if (cc == c) {
iterator.remove();
break;
}
iterator.remove();
}
}
list.add(c); // 添加到窗口
}
ans = Math.max(ans, list.size()); // 最后一个元素
return ans;
}
总结
算法:滑动窗口、双指针
数据结构:String、List