无重复字符的最长子串(滑动窗口算法,暴力双指针)

题目:

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

示例 :

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

一,滑动双指针

如图:

 代码:

 public static int lengthOfLongestSubstring(String s) {
        int length = s.length();
        if (length == 1) {
            return 1;
        }
        if (length == 0) {
            return 0;
        }
        Set<Character> characterSet = new HashSet();
        //末尾指针
        int end = -1;
        int max = 0;
        //从开始指针进行遍历
        for (int start = 0; start < length; start++) {
            // 如果,set集合不包含end+1指针所在的字符,再将end+1的字符加入set,并将指针end+1+1后移,则窗口增大
            //当start加1后,并且删除Set中start指针所在的字符,再判断end+1+1所在字符是否包含在set里,如果包含,再将start+1,则窗口在缩小。
            while (end + 1 <= length - 1 && !characterSet.contains(s.charAt(end + 1))) {
                characterSet.add(s.charAt(end + 1));
                ++end;
            }
            //当末尾指针,指在字符串尾部,这时,之后的字串肯定是越来越小,直接返回,
            if (end == length - 1) {
                max = Math.max(max, end - start + 1);
                return max;
            }
            max = Math.max(max, end - start + 1);
            //删除Set中start指针所在的字符
            characterSet.remove(s.charAt(start));

        }
        return max;

    }

解释:

 新建一个set用于存放不重复的字符,set集合不包含end+1指针所在的字符,再将end+1指针所在字符加入set,并将指针end+1(后移),则窗口增大,直到set集合包含end+1指针所在的字符。随后求出最大子串,删除set中start指针所在的字符,start加1(指针后移),再判断end+1指针所在字符是否包含在set里,如果包含,删除Set中start指针所在的字符,再将start+1,则窗口在缩小,直到set集合里不包含end+1指针所在字符,接着就是移动end指针,不断窗口后移,找最长子串,直到end指向字符串尾端。

二,暴力双指针:

代码:

public static int lengthOfLongestSubstring(String s) {
        int length = s.length();
        //当长度为1则返回1
        if (length == 1) {
            return 1;
        }
        //当长度为0,直接返回0
        if (length == 0) {
            return 0;
        }
        //用于存储不重复的字符串
        Set<Character> characterSet = new HashSet();
        //末尾指针
        int end = 0;
        //最大子串
        int max = 0;
        //从开始指针进行遍历
        for (int start = 0; start < length; start++) {
            //当末尾指针小于等于字符长度,并且set集合不包含该字符,则加入set,并且将指针后移,直到出现重复字符
            while (end <= length - 1 && !characterSet.contains(s.charAt(end))) {
                characterSet.add(s.charAt(end));
                end++;
            }
            //当末尾指针,指在字符串尾部,这时,之后的字串肯定是越来越小,直接返回,
            if (end >= length - 1) {
                return max = Math.max(max, end - start);
            }
            //end-start ,表明包含开始指针,不包含末尾指针,因为上面是将末尾指针加1再去判断是不是重复字符
            max = Math.max(max, end - start);
            //将set清零
            characterSet.clear();
            //将末尾指针指向开始指针,因为for循环结束,start+1,所以,end=start+1,重新循环,判读无重复字符的字串的长度
            end = start + 1;
        }

        return max;
    }

解释:

从start进行遍历,当end指针所在字符,不包含在set集合里面, 将end指针所在字符,加入set集合里面,将end+1(指针后移),直到set集合包含end指针包含所在字符,如果end指针指向字符末端,或者超过字符长度,则直接返回最大字符。当end指针不指向末尾,求出最大子串,再将set集合清空,将end指针指向start指针,继续从start开始遍历找最大子串

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值