美文网首页
2018-11-28 无重复字符的最长子串

2018-11-28 无重复字符的最长子串

作者: 天际神游 | 来源:发表于2018-11-28 11:15 被阅读0次

    题目:

    3. 无重复字符的最长子串

    解法:

    思想, 使用滑动窗口, 下标 i 表示左边界, 下标 j 表示右边界. i 和 j 之间的长度是不重复的子串的长度.

    j 一步一步的走, 用一个HashMap存储j走过的元素(元素 --> 下标).
    对于i来说, 只有当出现重复元素的时候才需要更新. 当重复的时候, 取重复位置的最大下标+1. 但是我们不删除过往的元素, 也就是说过期的元素依然会存在于HashMap中, 这时候我们就直接取 (重复元素的下标+1) 和 当前位置的最大值.
    然后每轮结束的时候计算一次长度, 和之前的相比取最大.

    流程为:
    ==> j 往右边走;
    ==> 遇到重复元素, i 需要是否需要更新, 取决于重复元素是否过期(也就是重复的元素的下标比 i 的小, 就不更新 i ) ;
    把 j 位置的元素压入HashMap;
    计算长度, 和历史相比取最长;
    直到结束.

    public int lengthOfLongestSubstring(String s) {
        // 滑动窗口, 用 HashMap判断重复
        Map<Character, Integer> map = new HashMap<>();
        int res = 0;
        for (int i = 0, j = 0; j < s.length(); j++) {
            // 当前j位置的字符
            char ch = s.charAt(j);
            if (map.containsKey(ch)) {
                i = Math.max(map.get(ch) + 1, i);
            }
            map.put(ch, j);
            res = Math.max(res, j - i + 1);
        }
        return res;
    }
    

    可以使用数组优化Hashmap

    public int lengthOfLongestSubstring(String s) {
        // 使用数组优化HashMap, 把数组看作是特殊的Hashmap
        int[] map = new int[128];
        int res = 0;
        for (int i = 0, j = 0; j < s.length(); j++) {
            char ch = s.charAt(j);
            // 每次都取最大的i, 因为index比i小的元素被认为是过期的, 无效的
            i = Math.max(map[ch], i);
            // 每次都put
            map[ch] = j + 1;
            // 计算总长
            res = Math.max(res, j - i + 1);
        }
        return res;
    }
    

    相关文章

      网友评论

          本文标题:2018-11-28 无重复字符的最长子串

          本文链接:https://www.haomeiwen.com/subject/brkaqqtx.html