LeetCode热题Hot100 - 03 - 无重复字符的最长子串

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

LeetCode热题Hot100 - 03 - 无重复字符的最长子串_第1张图片 

    public int lengthOfLongestSubstring1(String s) {
        if (s.length() == 0) {
            return 0;
        }
        int res = 0;
        // 左指针,i相当于右指针
        int left = 0;
        Map table = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (table.containsKey(c)) {
                left = Math.max(left, table.get(c) + 1);
            }
            table.put(c, i);
            res = Math.max(res, i - left + 1);
        }

        return res;
    }

对于 left = Math.max(left, table.get(c) + 1); 【力扣一位老哥在评论区的解释】

如果当前字符 c 包含在 map中,此时有2类情况:

  • 当前字符包含在当前有效的子串中,如:abca,当我们遍历到第二个a,当前有效最长子串是 abc,我们又遍历到a, 那么此时更新 left 为 map.get(a)+1=1,当前有效子串更新为bca;
  • 当前字符不包含在当前最长有效子串中,如:abba,我们先添加a,b进map,此时left=0,我们再添加b,发现map中包含b, 而且b包含在最长有效子串中,就是1)的情况,我们更新 left=map.get(b)+1=2,此时子串更新为 b,而且map中仍然包含a,map.get(a)=0; 随后,我们遍历到a,发现a包含在map中,且map.get(a)=0,如果我们像1)一样处理,就会发现 left=map.get(a)+1=1,实际上,left此时 应该不变,left始终为2,子串变成 ba才对。 为了处理以上2类情况,我们每次更新left,left=Math.max(left , map.get(ch)+1). 另外,更新left后,不管原来的 s.charAt(i) 是否在最长子串中,我们都要将 s.charAt(i) 的位置更新为当前的i, 因此此时新的 s.charAt(i) 已经进入到当前最长的子串中!

你可能感兴趣的:(LeetCode,热题,HOT,100,leetcode,算法,数据结构,最长子串,java)