无重复字符的最长子串(中等)

该博客介绍了如何使用滑动窗口算法解决寻找字符串中最长无重复字符子串的问题。通过设置两个指针作为窗口的左右边界,并利用HashSet存储窗口内的字符,避免重复,从而有效地找到最长子串。示例代码展示了具体实现过程,包括移动指针、更新最长子串长度等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

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

示例1

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

示例2

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

示例3

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

做题思路

在寻找不含有重复字符的最长字串的时候,我们可以通过依次递增地枚举子串的起始位置来实现。假设我们选择字符i个字符作为起始位置,并且得到了不包含重复字符的最长子串的结束位置为r。那么当我们选择第i+1个字符作为起始位置时i+1到r的字符是不重复的,并且由于少了i个字符,我们可以尝试继续增大r,直到右侧出现了重复字符为止。

这个过程我们可以通过滑动窗口来实现:

  • 使用两个指针i和r表示窗口的左右边界,i代表枚举自子串的起始位置,r为不含有重复字符的子串的右边界;
  • 除了第一次枚举之后的每一次枚举,我们都会将左指针向右移动一格,表示开始枚举下一个字符作为起始位置,在保证左右指针对应的子串中没有重复字符的前提下不断地向右移动右指针,记录下每次枚举的子串的长度;
  • 枚举结束后,找到的最长的子串的长度即为答案。

代码

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int len=s.length();
        if(len==0) return 0;
        int res=0; //存储最后结果
        int r=-1; //无重复字符的子串的右边界
        Set<Character> set=new HashSet<Character>();
        for(int i=0;i<len;i++){
            if(i!=0){
                set.remove(s.charAt(i-1)); //左指针向右移动一格,移除一个字符
            }
            while(r+1<len && !set.contains(s.charAt(r+1))){
                set.add(s.charAt(r+1)); //只要无重复字符且不超过字符串长度,就不断添加新的字符
                r++; //指针右移
            }
            res=Math.max(res,r-i+1); //每结束一次遍历,就记录下当前的最长子串的长度
        }
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值