题目
给定一个字符串 s ,请你找出其中不含有重复字符的 最长连续子字符串 的长度。
- 输入与输出
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。 请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
思路
暴力遍历 + HashSet(超时!!!超时!!!超时!!!)
- 双层嵌套遍历字符串;
- 判断 set 是否能成功添加,如果能添加,比较当前长度与历史长度的大小;
- 如果不能添加, set 重置,添加当前字符。
滑动窗口 + HashSet
- 初始化滑动窗口(与 p 同时赋值,保证 s 和 p 的长度一样);
- 遍历字符串;
- 如果当前 set 包含字符串,那么删,删到不包含为止;
- 添加当前字符;
- 比较当前长度与历史长度大小。
优化滑动窗口 + 自制哈希表
- 思路与 滑动窗口 + HashSet 一样。
代码
- 暴力遍历 + HashSet(超时!!!超时!!!超时!!!)
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
int res = 1;
for (int i = 0; i < s.length(); i++) {
Set<Character> set = new HashSet<>();
set.add(s.charAt(i));
boolean exists = true;
for (int j = i+1; j < s.length(); j++) {
exists = set.add(s.charAt(j));
if (exists) {
res = Math.max(res,set.size());
}else {
set.clear();
set.add(s.charAt(j));
}
}
}
return res;
}
}
- 滑动窗口 + HashSet
class Solution {
public int lengthOfLongestSubstring(String s) {
// 如果当前字符串为 "", 那么直接返回
if (s == null || s.length() == 0) {
return 0;
}
// 定义结果以及 HashSet
int res = 1;
Set<Character> set = new HashSet<>();
// 滑动窗口初始大小
int left = 0;
int right = 0;
while (right < s.length()) {
char tmp = s.charAt(right);
// 如果当前包含, 那么删到不包含为止
while (set.contains(tmp)) {
set.remove(s.charAt(left));
left++;
}
// 添加字符
set.add(tmp);
// 比较大小
res = Math.max(set.size(),res);
// 窗口移动
right++;
}
// 返回结果
return res;
}
}
- 优化滑动窗口 + HashSet
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
int[] map = new int[128];
int res = 0;
List<Character> list = new ArrayList<>();
int right = 0;
int left = 0;
while (right < s.length()) {
int tmp = s.charAt(right)-32;
map[tmp]++;
if (map[tmp] > 1) {
res = Math.max(right-left,res);
while (map[tmp] > 1) {
int remove = s.charAt(left)-32;
map[remove]--;
left++;
}
}
right++;
}
res = Math.max(res,s.length()-left);
return res;
}
}
- 优化滑动窗口 + 自制哈希表
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
int[] map = new int[128];
int res = 0;
List<Character> list = new ArrayList<>();
int right = 0;
int left = 0;
while (right < s.length()) {
int tmp = s.charAt(right)-32;
map[tmp]++;
if (map[tmp] > 1) {
res = Math.max(right-left,res);
while (map[tmp] > 1) {
int remove = s.charAt(left)-32;
map[remove]--;
left++;
}
}
right++;
}
res = Math.max(res,s.length()-left);
return res;
}
}