力扣热门100题 - 3.无重复字符的最长子串
- 题目描述:
- 示例:
- 提示:
- 解题思路 (滑动窗口 哈希表):
- 代码:
题目链接:3. 无重复字符的最长子串
题目描述:
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
解题思路 (滑动窗口 哈希表):
这道题可以使用滑动窗口的思想来解决问题,其基本思路如下:
- 定义一个窗口,用来存储不含重复字符的子串。
- 使用两个指针
l
和r
来表示窗口的左右边界,初始时两者都指向字符串的开头。 - 不断向右移动右指针
r
,同时检查当前字符是否在窗口内已经存在:- 如果已经存在,则移动左指针
l
直到窗口内不含有重复字符为止。 - 如果不存在,则将当前字符加入窗口,并更新最长子串的长度。
- 如果已经存在,则移动左指针
- 在移动过程中,维护一个变量
maxLen
来记录最长不含重复字符的子串的长度。 - 最终返回
maxLen
即为所求的结果。
具体步骤可以总结为以下几点:
- 使用 HashSet 来记录窗口内已经存在的字符,保证查找的时间复杂度为 O(1)。
- 使用两个指针
l
和r
来表示窗口的左右边界,滑动窗口时可以通过移动指针来更新窗口。 - 在每次滑动窗口时,更新
maxLen
来记录最长不含重复字符的子串的长度。
时间复杂度: O(n)
这个算法的时间复杂度为 O(n),其中 n 是字符串的长度,因为每个字符最多被访问两次:一次是向右扩展右指针,一次是向右移动左指针。
代码:
class Solution {public int lengthOfLongestSubstring(String s) {HashSet<Character> hs = new HashSet<>();int len = s.length();int maxLen = 0;int l = 0;int r = 0;while(r < len){char c = s.charAt(r);if (hs.contains(c)){hs.remove(s.charAt(l));l++;}else {hs.add(c);r++;maxLen = maxLen > (r-l) ? maxLen : (r - l);}}return maxLen;}
}