关于LeetCode中第三题的最长子串

题目是这样子的

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

这道题主要使用到的思路是滑动窗口,每当我们选择一个字符作为查询的开始之后,每次搜到的子串都要判断是否存在重复的字符,如果存在,那么当前开始的字符的最长子串就是确定的。

打个比方,测试用例中的abcabcbb,当我们选择第一个字符a作为开始,我们会筛选到以下子串

  1. ab
  2. abc
  3. abca

当我们在搜到第三个子串时,发现当前字符a已经存在了,则可以确定第一个字符a的最长子串就是子串2。这个就是滑动窗口的设计,需要两个指针left和right,其中每次搜索时left固定,然后向右移动right,只要出现重复的字符,就修改left的位置。

这里还有一个设计,就是关于当前搜索的子串存储。可以用一个Map<Character,Integer>用来存储当前的子串,每次遇到重复的字符,都要把上一个字符的位置删掉,也就是把当前left指定的字符去掉,换成当前重复所在的位置。

整理之后的代码就是

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if (s.length() == 0) {
            return 0;
        }

        if (s.length() == 1) {
            return 1;
        }

        char[] cs = s.toCharArray();
        Map<Character, Integer> map = new HashMap<>();
        int left = 0;
        int max = 0;

        // left固定从0开始,而right指针则可以从第二个字符开始
        for (int right = left ; right < cs.length; right ++) {
            // 如果当前right对应的字符在map中重复出现,需要判断是否在窗口里面
            // 例如FABCDFCBGH,如果此时left的位置是A,而right的位置是第二个F
            // 那么上一次出现F的时候不在窗口里面,不影响A的最长子串获取
            // 但是如果left是B,而right指向了第二个C,而C第一次出现在窗口里面,
            // 则确定了B的最长子串,就需要移动left到C第一次出现的位置的下一个字符
            // 为啥是由重复字符确定left的指针位置呢,因为在B到C第一次出现之前的位置都是筛选过的,
            // B和C第一出现的中间字符最大也不可能超过B开始的子串,所以得从C第一次出现的下个字符开始
            // right是当前搜索的字符,所以不用 <= 
            if (map.containsKey(cs[right]) && map.get(cs[right]) >= left && map.get(cs[right]) < right) {
                left = map.get(cs[right]) + 1;
            }
            // 把当前字符和位置塞入Map中,这样也可以实时更新字符的位置,顺便把重复字符的位置更新
            map.put(cs[right], right);
            // max表示最大子串的长度
            max = Math.max(max, right - left + 1);
        }
        return max;
    }
}

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值