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

Given a string s , find the length of the longest substring t  that contains at most 2 distinct characters.

Example 1:

Input: "eceba"
Output: 3
Explanation: tis "ece" which its length is 3.

Example 2:

Input: "ccaabbb"
Output: 5
Explanation: tis "aabbb" which its length is 5.

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

时间O(n)

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

 1 /**
 2  * @param {string} s
 3  * @return {number}
 4  */
 5 var lengthOfLongestSubstringTwoDistinct = function (s) {
 6     let map = new Map();
 7     let left = 0;
 8     let max = 0;
 9     for (let right = 0; right < s.length; right++) {
10         map.set(s[right], right);
11         if (map.size > 2) {
12             let leftMostChar = null;
13             let leftMostIndex = Infinity;
14             for (let [char, index] of map) {
15                 if (index < leftMostIndex) {
16                     leftMostChar = char;
17                     leftMostIndex = index;
18                 }
19             }
20             map.delete(leftMostChar);
21             left = leftMostIndex + 1;
22         }
23         max = Math.max(max, right - left + 1);
24     }
25     return max;
26 };

另外一种模板写法,其他同类题型都可用。

Java实现

 1 class Solution {
 2     public int lengthOfLongestSubstringTwoDistinct(String s) {
 3         // corner case
 4         if (s == null || s.length() == 0) {
 5             return 0;
 6         }
 7 
 8         // normal case
 9         int[] map = new int[256];
10         int start = 0;
11         int end = 0;
12         int maxLen = Integer.MIN_VALUE;
13         int counter = 0;
14         while (end < s.length()) {
15             char c1 = s.charAt(end);
16             if (map[c1] == 0) {
17                 counter++;
18             }
19             map[c1]++;
20             end++;
21             while (counter > 2) {
22                 char c2 = s.charAt(start);
23                 if (map[c2] == 1) {
24                     counter--;
25                 }
26                 map[c2]--;
27                 start++;
28             }
29             maxLen = Math.max(maxLen, end - start);
30         }
31         return maxLen;
32     }
33 }

JavaScript实现

 1 /**
 2  * @param {string} s
 3  * @return {number}
 4  */
 5 var lengthOfLongestSubstringTwoDistinct = function(s) {
 6     // corner case
 7     if (s == null || s.length == 0) {
 8         return 0;
 9     }
10 
11     // normal case
12     let start = 0;
13     let end = 0;
14     let maxLen = -Infinity;
15     let counter = 0;
16     let map = {};
17     while (end < s.length) {
18         let c1 = s.charAt(end);
19         if (map[c1] == null || map[c1] <= 0) {
20             counter++;
21         }
22         map[c1] = map[c1] + 1 || 1;
23         end++;
24         while (counter > 2) {
25             let c2 = s.charAt(start);
26             if (map[c2] == 1) {
27                 counter--;
28             }
29             map[c2]--;
30             start++;
31         }
32         maxLen = Math.max(maxLen, end - start);
33     }
34     return maxLen;
35 };

sliding window相关题目

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/12376705.html