LeetCode 3. 无重复字符的最长子串 && 滑动窗口

题目要求

原题目链接:3. 无重复字符的最长子串

题目要求如下:

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

示例如下:

示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
———————————————————————————————————————————
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
———————————————————————————————————————————
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
———————————————————————————————————————————
示例 4:
输入: s = “”
输出: 0

解法:滑动窗口

思路

从头依次对字符串s进行遍历,每一次遍历到的字符作为子串的起始字符,再寻找以当前字符为起始的无重复最长子串,一次遍历即可解决问题。

可以使用一个Set集合来维护每一次遍历存储的无重复最长子串来对普通的遍历进行优化。假设现有字符串abcda,那么第一次遍历最长的无重复最长字串就是abcd,相应第二次遍历的角色bcda,其中bcd部分是在第二次遍历是没有必要进行重复比较的,因此可以使用一个集合存储,每一次遍历时移除Set集合首位,余下的字符串也一定是无重复的,继续向原字符串后比较集合,空间换时间。

解题过程中一个指针总是指向新子串起始位置,另一个指针总是寻找并指向当前最长无重复子串的结尾位置,两个指针动态组成不定长的子串,故名滑动窗口,本质还是双指针的一种。

完整AC代码

class Solution {
    public int lengthOfLongestSubstring(String s) {
        Set<Character> set = new HashSet<Character>();
        int max = 0;
        int right = -1;
        for(int i = 0; i < s.length(); i++){
            if(i != 0)set.remove(s.charAt(i - 1));
            while(right + 1 < s.length() && !set.contains(s.charAt(right + 1)))set.add(s.charAt(right++ + 1));
            max = Math.max(max, set.size());
        }
        return max;
    }
}

复杂度分析

时间复杂度:O(N),n字符串长度,实际上两个指针都需要对字符串进行一次遍历时间复杂度O(2N),故总时间复杂度O(N)。
空间复杂度:O(S),S表示字符串内可能包含的字符总个数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
滑动窗口是一种常用的算法技巧,可以用于解决一类问题,其中包括一些LeetCode上的题目。通过维护一个窗口,我们可以在线性时间内解决一些需要处理连续子数组或子字符串的问题。以下是一些常见的滑动窗口问题: 1. 最小覆盖子串(Minimum Window Substring):给定一个字符串S和一个字符串T,在S中找出包含T所有字符的最小子串。 2. 字符串的排列(Permutation in String):给定两个字符串s1和s2,判断s2是否包含s1的排列。 3. 找到字符串中所有字母异位词(Find All Anagrams in a String):给定一个字符串s和一个非空字符串p,找到s中所有是p的字母异位词的子串。 4. 替换后的最长重复字符(Longest Repeating Character Replacement):给定一个只包含大写英文字母的字符串s,你可以将一个字母替换成任意其他字母,使得包含重复字母的最长子串的长度最大化。 5. 至多包含两个不同字符最长子串(Longest Substring with At Most Two Distinct Characters):给定一个字符串s,找出至多包含两个不同字符最长子串的长度。 以上只是几个例子,滑动窗口可以应用于更多类型的问题。在解决这些问题时,我们通常使用两个指针来表示窗口的左右边界,并根据具体问题的要求移动窗口。在每次移动窗口时,我们可以更新窗口的状态,例如统计字符出现次数、判断窗口是否满足条件等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

7rulyL1ar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值