LeetCode 数据结构与算法之无重复字符的最长子串

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情

题目

无重复字符的最长子串

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

示例 1:

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

示例 2:

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

示例 3:

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

提示:

0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
复制代码

题解

解题分析

解题思路

  1. 这个题目是一个典型的 “滑动时间窗” 算法的题目.

  2. 我们可以用快慢指针的方式来进行字符串的读取,i 表示子串的开始位置,rk 表示子串的当前位置。

我们可以利用 hash 来判断不重复子串。如果 hash 表中存在该字符串,就进入下次循环;如果不存在,就放入集合中然后在再移动右指针。

扫描二维码关注公众号,回复: 13784395 查看本文章
  1. 最后通过 ans 来保存最大子串长度,然后对比的就是 rk - i + 1 就是右指针- 左指针 + 1

复杂度 时间复杂度 O(N)
空间复杂度 O(|Σ|)

解题代码

题解代码如下(代码中有详细的注释说明):

class Solution {
    public int lengthOfLongestSubstring(String s) {
        // hash 集合,记录每个字符串是否出现过
        Set<Character> occ = new HashSet<>();
        int n = s.length();
        // 右指针,初始值为 -1, 相当于我们字符串在左边界的左侧
        int rk = -1, ans = 0;
        for (int i = 0; i < n; i++) {
            if (i != 0) {
                // 左指针右移,删除一个字符
                occ.remove(s.charAt(i - 1));
            }
            while (rk + 1 < n && !occ.contains(s.charAt(rk + 1))) {
                // 指针右移
                occ.add(s.charAt(rk + 1));
                rk++;
            }

            // 第 i 到 rk 一个字符串是一个,最长的无重复的子串
            ans = Math.max(ans, rk - i + 1);
        }
        return ans;
    }
}
复制代码

提交后反馈结果(由于该题目没有进行优化,性能一般):

image.png

参考信息

猜你喜欢

转载自juejin.im/post/7085370521398804510