[LeetCode] 159. Longest Substring with At Most Two Distinct Characters

Given a string s, return the length of the longest substring that contains at most two distinct characters.

Example 1:
Input: s = "eceba"
Output: 3
Explanation: The substring is "ece" which its length is 3.

Example 2:
Input: s = "ccaabbb"
Output: 5
Explanation: The substring is "aabbb" which its length is 5.

Constraints:
1 <= s.length <= 105
s consists of English letters.

至多包含两个不同字符的最长子串。

题意是给一个字符串,请返回一个最长子串的长度,子串至多包含两个不同字符的最长子串。

思路 - 滑动窗口,类似76题

这题依然是用到 sliding window 的思想。给左右两个指针,并且创建一个 hashmap,key 是遍历到的字母,value 是字母最后一次出现位置的 index。扫描的时候,一开始只让右指针移动,把遍历到的字母和当前的坐标值加入hashmap。此时最大子串的长度就是左右指针的间距。当右指针遍历到第三个不同字母的时候,需要扫描hashmap,找到value(记为leftmost)最小的那个key并且删除这个键值对。此时左指针的位置是leftmost + 1。

复杂度

时间O(n)
空间O(1) - 虽然有 hashmap 但是 size 很小,只有 26 个字母

代码

Java实现

class Solution {
    public int lengthOfLongestSubstringTwoDistinct(String s) {
        // corner case
        if (s == null || s.length() == 0) {
            return 0;
        }
        
        // normal case
        int start = 0;
        int end = 0;
        int res = Integer.MIN_VALUE;
        int counter = 0;
        int[] map = new int[256];
        while (end < s.length()) {
            char c1 = s.charAt(end);
            if (map[c1] == 0) {
                counter++;
            }
            map[c1]++;
            end++;
            while (counter > 2) {
                char c2 = s.charAt(start);
                map[c2]--;
                if (map[c2] == 0) {
                    counter--;
                }
                start++;
            }
            res = Math.max(res, end - start);
        }
        return res;
    }
}

JavaScript实现

/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstringTwoDistinct = function (s) {
    let map = new Map();
    let left = 0;
    let max = 0;
    for (let right = 0; right < s.length; right++) {
        map.set(s[right], right);
        if (map.size > 2) {
            let leftMostChar = null;
            let leftMostIndex = Infinity;
            for (let [char, index] of map) {
                if (index < leftMostIndex) {
                    leftMostChar = char;
                    leftMostIndex = index;
                }
            }
            map.delete(leftMostChar);
            left = leftMostIndex + 1;
        }
        max = Math.max(max, right - left + 1);
    }
    return max;
};
posted @ 2020-04-03 10:03  CNoodle  阅读(317)  评论(0编辑  收藏  举报