滑动窗口
要找到一个字符串中不含重复字符的最长子串的长度,可以使用滑动窗口技术。这种方法可以在 O(n) 时间复杂度内解决问题,其中 n 是字符串的长度。
滑动窗口算法
滑动窗口的基本思想是使用两个指针来表示一个窗口,这个窗口内的字符是当前不含重复字符的子串。我们通过调整窗口的边界来找到最长的子串。
实现步骤
-
初始化:使用两个指针
left
和right
,都初始化为 0。使用一个集合charSet
来存储当前窗口内的字符。使用一个变量maxLength
来记录最长子串的长度。 -
移动右指针:逐步增加右指针
right
,将字符加入到charSet
中。 -
检查重复:如果加入的字符导致重复,则移动左指针
left
,并从charSet
中移除字符,直到窗口内不再有重复字符为止。 -
更新最大长度:在每次调整窗口后,更新
maxLength
为当前窗口的长度(right - left + 1
)和maxLength
的较大值。 -
继续移动右指针,直到遍历完整个字符串。
示例代码
以下是使用 Python 实现的代码:
class Solution {
public int lengthOfLongestSubstring(String s) {
int ans = 0;
int len = s.length();
// corner case
if (len <= 1) {
return len;
}
// core
int l = 0, r = 0;
Set<Character> set = new HashSet<>();
while (r < len) {
if (!set.contains(s.charAt(r))) {
set.add(s.charAt(r));
ans = Math.max(r - l + 1, ans);
r++;
} else {
set.remove(s.charAt(l));
l++;
}
}
return ans;
}
}
def length_of_longest_substring(s: str) -> int:
char_set = set()
left = 0
max_length = 0
for right in range(len(s)):
# 如果当前字符在set中,移动左指针,直到没有重复字符
while s[right] in char_set:
char_set.remove(s[left])
left += 1
# 将当前字符加入set
char_set.add(s[right])
# 更新最大长度
max_length = max(max_length, right - left + 1)
return max_length
# 示例
s = "abcabcbb"
print(length_of_longest_substring(s)) # 输出: 3
解释
- 集合
charSet
:用于存储当前窗口内的字符,保证没有重复。 - 左指针
left
:用于缩小窗口,当发现重复字符时,移除左边的字符直到没有重复。 - 右指针
right
:用于扩大窗口,遍历字符串。 - 最大长度
maxLength
:用于记录当前找到的最长无重复字符子串的长度。
这种方法的优点是只需遍历字符串一次,因此时间复杂度是 O(n),适合处理较长的字符串。