LeetCode Algorithms 3 无重复字符的最长子串

1. 题目描述

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

1
2
3
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

1
2
3
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

1
2
3
4
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

2. 题解

2.1. 思路1:暴力法

用两层循环遍历所有子串,取不重复的最长的

1
2
3
4
5
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// 取不重复的最长,更新maxLen
}
}

2.2. 思路2:滑动窗口

保证窗口[i, j)是当前无重复字符的局部最长子串

2.3. Java实现

思路1:暴力法,用HashSet进行判重。如果[i,j]范围内的子串出现重复,j就不用必向后遍历了,直接break

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
int n = s.length();
int maxLen = 1;
for (int i = 0; i < n; i++) {
Set<Character> set = new HashSet<>();
set.add(s.charAt(i));
for (int j = i + 1; j < n; j++) {
if (set.contains(s.charAt(j))) {
break;
}
set.add(s.charAt(j));
maxLen = Math.max(maxLen, j - i + 1);
}
}
return maxLen;
}
}

思路2:滑动窗口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Set<Character> set = new HashSet<>();
int ans = 0, i = 0, j = 0;
while (i < n && j < n) {
if (!set.contains(s.charAt(j))) {
// 局部最长子串 + 1
set.add(s.charAt(j++));
// 更新全局最长子串的长度
ans = Math.max(ans, j - i);
} else {
// 窗口中有重复串存在,i前移
set.remove(s.charAt(i++));
}
}
return ans;
}
}
panchaoxin wechat
关注我的公众号
支持一下