【LeetCode】3、无重复字符的最长子串

题目链接:

https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

变更:无重复子串的最长子串的内容(求子串,原题求子串长度)

思路:双指针滑动窗口法

思路分析示例

frankissohandsome为例,我们要从中找出我们想要的子串,那少不了需要遍历,我们设置两个变量from,to,分别存储寻找的目标子串在原字符串中的首尾位置。

首先,fromto的初始值都为0(String的序号从0开始),子串长度length = 1,最大子串长度maxLength = 1。

然后,我们将to的指向往后移动,并判断新遍历的字符是否已经存在于子串中,如果不存在,则将其加入子串中,并将length进行自增。

在这里插入图片描述

直到找到一个已存在于子串中的字符,或者to到达字符串的末尾。这里,我们找到了一个重复的s,序号为7,此时的子串为frankis,将此时的子串长度与最大子串长度相比较(目前为0),如果比最大子串长度大,则将最大子串长度设置为当前子串长度7
在这里插入图片描述

接下来,我们继续寻找符合条件的子串,这里比较关键的一点是下一个子串的起始位置,这里我们将from直接跳到了序号为7的位置,因为包含ss的子串显然都不能满足要求。
在这里插入图片描述

依照之前的方法,找到第二个候选的子串sohand,长度为6,比目前的最大子串长度小,所以不是目标子串。
在这里插入图片描述

接着继续寻找,找到另一个候选子串ohands,长度小于最大子串长度,不是我们的目标子串
在这里插入图片描述

继续寻找

在这里插入图片描述

to到达了字符串末尾,找到另一个候选子串handsome,长度大于最大子串长度,这就是我们的目标子串。
在这里插入图片描述

Java代码

    public static int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> map = new HashMap<>();
        int result = 0;
        for (int start = 0, end = 0; end < s.length(); end++) {
            char strChar = s.charAt(end);
            if (map.containsKey(strChar)) {
                start = Math.max(start, map.get(strChar));
            }
            result = Math.max(result, end - start + 1);
            map.put(strChar, end + 1);
        }
        return result;
    }

    public static String longestSubstring(String s) {
        Map<Character, Integer> map = new HashMap<>();
        int result = 0;
        int begin = 0;
        for (int start = 0, end = 0; end < s.length(); end++) {
            char strChar = s.charAt(end);
            if (map.containsKey(strChar)) {
                start = Math.max(start, map.get(strChar));
            }

            if (end - start + 1 >= result) {
                begin = start;
                result = end - start + 1;
            }
//            result = Math.max(result, end - start + 1);
//            System.out.println("start:"+start+" end:"+end+" result"+result);
            map.put(strChar, end + 1);
        }
        return s.substring(begin, begin + result);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值