LeetCode 第3题:无重复字符的最长子串
引言
大家好!今天我们要聊的这道题目在LeetCode上可以说是经典中的经典,它就像是编程世界中的“小李飞刀”,每次出手都能让新手和老手们汗颜。这道题目就是——LeetCode 第3题:“无重复字符的最长子串”。
这道题目听起来简单,实则有点考验我们的耐心和技巧。题目描述如下:给定一个字符串 s
,请你找出其中不含有重复字符的最长子串的长度。
示例:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
思路解析
朴素的暴力解法
最简单直接的办法就是暴力破解,遍历所有可能的子串,然后检查每个子串是否有重复字符。这种方法就像是用筛子筛沙子,效率很低。暴力解法的时间复杂度是 O(n^3),实在是不适合长字符串。
滑动窗口法
要高效地解决这个问题,我们需要用到滑动窗口法。这种方法就像是我们在拥挤的地铁里找座位,一直在前进的过程中找出最长的“独享座位”。
滑动窗口的核心思想是:
- 用两个指针表示窗口的起点和终点。
- 逐步移动终点指针,扩展窗口。
- 当发现重复字符时,移动起点指针,缩小窗口,直到窗口内没有重复字符。
- 记录窗口的最大长度。
详细步骤
- 创建一个哈希集合(
HashSet
)来保存当前窗口内的字符。 - 初始化两个指针
left
和right
,都指向字符串的起点。 - 移动右指针
right
,如果字符不在集合中,就把字符加入集合并更新最大长度。 - 如果字符在集合中,就移动左指针
left
,直到字符不再重复。 - 重复上述步骤直到右指针遍历完整个字符串。
代码实现
用Java来实现这个算法非常简单。代码如下:
import java.util.HashSet;
import java.util.Set;
public class Solution {
public int lengthOfLongestSubstring(String s) {
Set<Character> set = new HashSet<>();
int left = 0, right = 0, maxLength = 0;
while (right < s.length()) {
if (!set.contains(s.charAt(right))) {
set.add(s.charAt(right));
right++;
maxLength = Math.max(maxLength, right - left);
} else {
set.remove(s.charAt(left));
left++;
}
}
return maxLength;
}
}
图解
为了让大家更直观地理解滑动窗口法,我们用Mermaid语法来画图展示一下算法的过程。
假设我们有一个字符串 s = "abcabcbb"
。
通过这种方法,我们最终可以得到最长无重复字符子串的长度。
总结
好了,今天我们详细讲解了LeetCode第3题“无重复字符的最长子串”的解题思路和实现。滑动窗口法是一种非常高效的解决方案,时间复杂度为 O(n),适用于大部分实际场景。
最后提醒大家,不管是写代码还是挤地铁,找到最佳位置和路径都是一门学问。希望大家能在编码的旅途中找到属于自己的最佳“座位”。
如果本文对您有所帮助的话,请收藏文章、关注作者、订阅专栏,感激不尽。