个人主页:五敷有你
系列专栏:算法分析与设计
⛺️稳中求进,晒太阳
给定一个字符串
s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke"
滑动窗口+双指针(快慢指针)
滑动窗口算法适用于解决具有子序列或子数组的问题,其中问题的解可以通过在输入序列中移动一个窗口(子序列或子数组)来得到。一些常见的情况下可以选择滑动窗口算法包括:
定义两个指针
start
和end
,分别表示当前子串的起始和结束位置。使用一个哈希集合(例如
HashSet
)来存储当前窗口内的字符。初始化
start
和end
为 0,然后开始遍历字符串s
:a. 如果
s.charAt(end)
不在哈希集合中,说明可以将s.charAt(end)
加入当前窗口,然后将end
指针右移,更新最长子串的长度。b. 如果
s.charAt(end)
在哈希集合中,说明出现了重复字符。此时需要将s.charAt(start)
移出窗口,将start
指针右移。重复步骤 3 直到
end
指针遍历完整个字符串。返回最长子串的长度。
class Solution {
public int lengthOfLongestSubstring(String s) {
Set charSet = new HashSet<>();
int start = 0, end = 0, maxLength = 0;
while (end < s.length()) {
if (!charSet.contains(s.charAt(end))) {
charSet.add(s.charAt(end));
end++;
maxLength = Math.max(maxLength, end - start);
} else {
charSet.remove(s.charAt(start));
start++;
}
}
return maxLength;
}
}
时间复杂度分析:
在这个算法中,每个字符最多被访问两次,即在 end
指针的移动过程中。start
指针和 end
指针分别向右移动,整个过程时间复杂度是 O(n)。因此,这个算法的时间复杂度是线性的,其中 n 是字符串的长度。
遍历字符串的过程只涉及两个指针的移动和哈希集合的插入、删除操作,这些操作都是 O(1) 的复杂度。因此,整体时间复杂度为 O(n)。