Title description
// 48. 最长不含重复字符的子字符串
// 力扣
// 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长
// 子字符串的长度。
answer
双指针滑窗法 /
// 力扣
// 左右指针构成滑动窗口,并用一个HashSet维护已被遍历过的字符
// 执行用时:10 ms, 在所有 Java 提交中击败了20.89%的用户
// 内存消耗:38.6 MB, 在所有 Java 提交中击败了34.39%的用户
import java.util.HashSet;
class Solution {
public int lengthOfLongestSubstring(String s) {
int res = 0; // 答案存储
int right = 0, left = 0; // 初始化右指针right,左指针left
// HashSet标记以遍历过的字符,如果字符出现过,会被存进set
HashSet<Character> set = new HashSet<>();
while (right < s.length()) {
char c = s.charAt(right); // 提取当前右指针所在字符c
while (set.contains(c)) // 如果c已经出现过
// 左指针准备右移,先去掉左指针字符在set中的备份,
// 说明该字符不再标记为已被使用,之后左指针右移
set.remove(s.charAt(left++));
// 右指针将当前遍历字符存入set,表示该字符已被使用
set.add(s.charAt(right));
right++; // 然后右指针right右移
res = Math.max(res, right - left); // 窗口长度和res中较大者更新为res
}
return res;
}
}
// 力扣
// 布尔数组记录元素已被使用
// 执行用时:2 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:38.5 MB, 在所有 Java 提交中击败了52.88%的用户
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s.length() == 0)
return 0;
char[] chars = s.toCharArray(); // s转为字符数组
boolean[] used = new boolean[128]; // 布尔数组used记录元素已被使用
int left = -1, right = 0, length = chars.length;
int res = 1; // 答案保存
// 右指针往右遍历
while (right < length) {
if (!used[chars[right]]) { // 如果right遍历元素未被使用
used[chars[right]] = true; // used记录right当前位置已被使用
right++; // right右移
}
else { // 如果right遍历元素已被使用
// 当left右移至right遍历位置,将使用标记转false后,循环停止
while(used[chars[right]]) {
left++; // left右移
// 第一次whilw循环时,因为right和left为相同元素,
// 所以left左移一次后,窗口长度才为不重复字符长度,
// 取窗口长度和res最大者更新res
res = Math.max(res, right-left);
used[chars[left]] = false; // left右移后遍历位标记转false
}
}
}
// 最后返回res和right-left-1最大者
return Math.max(res, right-left-1);
}
}