【LeetCode】Longest Substring with At Most Two Distinct Characters (2 solutions)

Longest Substring with At Most Two Distinct Characters

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

For example, Given s = “eceba”,

T is "ece" which its length is 3.

 

可与Longest Substring Without Repeating Characters对照看。

 

这个题很显然使用双指针进行遍历的,begin与end之间的窗口代表符合要求的字符子串。

解法一:

inWindow数组保存窗口中的两个不同字符。(若找不到两个不同的字符,直接返回字符串长度)

map<char, int>保存inWindow中两个字符在窗口中的出现次数。

判断新字符的标准为不等于inWindow数组的任一字符,那么就需要收缩begin,直到inWindow腾出空间给新字符。

class Solution 
{  
public:
    int lengthOfLongestSubstringTwoDistinct(string s) 
    {
        if(s == "")
            return 0;
        else if(s.size() <= 2)
            return s.size();

        //slip window [begin, end]
        //initial the window with two different chars
        int size = s.size();
        int begin = 0;
        int end = 1;
        while(end < size && s[end] == s[begin])
            end ++;
        //to here, end == size or s[end] != s[begin]
        if(end == size)
            return size;    //all chars are the same

        char inWindow[2] = {s[begin], s[end]};
        map<char, int> m;    //char->count map
        m[s[begin]] = end-begin;    //[begin,end) are all s[begin]
        m[s[end]] = 1;
        int longest = end-begin+1;
        end ++;
        while(end < size)
        {
            m[s[end]] ++;
            if(s[end] == inWindow[0] || s[end] == inWindow[1])
            //in window, extend end
                longest = max(longest, end-begin+1);
            else
            {//not in window, shrink begin
                //remove a char from window
                while(m[inWindow[0]] != 0 && m[inWindow[1]] != 0)
                {
                    m[s[begin]] --;
                    begin ++;
                }
                //to here, either m[inWindow[0]] == 0 or m[inWindow[1]] == 0
                if(m[inWindow[0]] == 0)
                    inWindow[0] = s[end];
                else
                    inWindow[1] = s[end];
            }
            end ++;
        }
        return longest;
    }
};

 

解法二:

由于A~Z,a~z的ASCII码不超过122,因此开辟128的数组record进行窗口中每个字符的计数。

再设置计数位count,记录当前窗口中有多少个不同的字符。

判断新字符的标准为record值为1(加入新字符之后)。

如果count>2,那么就需要收缩begin,直到s[begin]对应的计数为0,代表少了一类字符,count--

class Solution 
{  
public:
    int lengthOfLongestSubstringTwoDistinct(string s) 
    {
        if(s.size() <= 2)
            return s.size();
        int size = s.size();
        int record[128] = {0};    //record the appearance times of each char. Note 'z' is 122, 128 is enough.
        int begin = 0;
        int end = 0;
        int count = 0;    //distinct count
        int longest = 0;
        while(end < size)
        {
            record[s[end]] ++;
            if(record[s[end]] == 1)
            //new char
                count ++;

            while(count > 2)
            {//shrink
                record[s[begin]] --;
                if(record[s[begin]] == 0)
                    count --;
                //remove one char
                begin ++;
            }
            longest = max(longest, end-begin+1);
            end ++;
        }
        return longest;
    }
};

 

我编写的测试用例如下,上述两个解法代码全部通过。

int main()
{
    
    string str1 = "";                //expect: 0 ""
    string str2 = "a";                //expect: 1 "a"
    string str3 = "aa";                //expect: 2 "aa"
    string str4 = "aba";            //expect: 3 "aba"
    string str5 = "abcd";            //expect: 2 "ab"
    string str6 = "abcdedcba";        //expect: 3 "ded"
    string str7 = "abbcdededcba";    //expect: 5 "deded"
    string str8 = "eceba";            //expect: 3 "ece"
    string str9 = "abaece";            //expect: 3 "aba"
    string str10 = "ababcd";        //expect: 4 "abab"
    string str11 = "cababcd";        //expect: 4 "abab"
    string str12 = "abcdefgabcdefg";//expect: 2 "ab"
    string str13 = "ababababababab";//expect: 14 "ababababababab"

    Solution s;
    cout << s.lengthOfLongestSubstringTwoDistinct(str1) << endl;
    cout << s.lengthOfLongestSubstringTwoDistinct(str2) << endl;
    cout << s.lengthOfLongestSubstringTwoDistinct(str3) << endl;
    cout << s.lengthOfLongestSubstringTwoDistinct(str4) << endl;
    cout << s.lengthOfLongestSubstringTwoDistinct(str5) << endl;
    cout << s.lengthOfLongestSubstringTwoDistinct(str6) << endl;
    cout << s.lengthOfLongestSubstringTwoDistinct(str7) << endl;
    cout << s.lengthOfLongestSubstringTwoDistinct(str8) << endl;
    cout << s.lengthOfLongestSubstringTwoDistinct(str9) << endl;
    cout << s.lengthOfLongestSubstringTwoDistinct(str10) << endl;
    cout << s.lengthOfLongestSubstringTwoDistinct(str11) << endl;
    cout << s.lengthOfLongestSubstringTwoDistinct(str12) << endl;
    cout << s.lengthOfLongestSubstringTwoDistinct(str13) << endl;
}

 

posted @ 2014-12-28 16:00  陆草纯  阅读(1729)  评论(0编辑  收藏  举报