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.

 

给一个字符串,求这个字符串中,由两个字母组成的,连续的最长子串的长度。

 

虽然是hard,但是感觉并没有什么难度。

用ch1和preCh记录当前两个字母,preCh记录的是上一个字母(s.charAt(i-1)),same记录的是preCh这个字母重复出现的次数,这样出现第三个字母的时候,就可以直接得出从0到i由后两个字母组成的长度为same+1,并没有使用其他的数据结构。

时间O(n),空间O(1).

public class Solution {
    public int lengthOfLongestSubstringTwoDistinct(String s) {
        int len = s.length();
        if (len < 3){
            return len;
        }
        char ch1 = s.charAt(0);
        int same = 0;
        while (same < len && s.charAt(same) == ch1){
            same++;
        }
        if (same == len){
            return len;
        }
        char preCh = s.charAt(same);
        int result = same + 1;
        int ans = same + 1;
        int i = same + 1;
        same = 1;
        for (; i < len; i++){
            if (s.charAt(i) == preCh){
                result++;
                same++;
            } else if (s.charAt(i) == ch1){
                result++;
                same = 1;
                ch1 = preCh;
                preCh = s.charAt(i);
            } else {
                ch1 = preCh;
                preCh = s.charAt(i);
                ans = Math.max(ans, result);
                result = same + 1;
                same = 1;
            }
        }
        ans = Math.max(ans, result);
        return ans;
    }
}

 

2、还可以利用hashMap来做:(参考discuss)

  Map数目小于3的时候将字母和他的位置加入Map中。

  如果是大于等于3,那么找出距离位置hi最远的一个字母(leftMost),删掉,从leftMost的下一个字母开始到当前位置hi就是当前两个字母的长度。

public class Solution {
    public int lengthOfLongestSubstringTwoDistinct(String s) {
        if(s.length() < 1) return 0;
        HashMap<Character,Integer> index = new HashMap<Character,Integer>();
        int lo = 0;
        int hi = 0;
        int maxLength = 0;
        while(hi < s.length()) {
            if(index.size() <= 2) {
                char c = s.charAt(hi);
                index.put(c, hi);
                hi++;
            }
            if(index.size() > 2) {
                int leftMost = s.length();
                for(int i : index.values()) {
                    leftMost = Math.min(leftMost,i);
                }
                char c = s.charAt(leftMost);
                index.remove(c);
                lo = leftMost+1;
            }
            maxLength = Math.max(maxLength, hi-lo);
        }
        return maxLength;
    }
}

 

 

 

3、其实不算算法,就是把s先转换成char[]。这样就会达到最快。

public class Solution {
    public int lengthOfLongestSubstringTwoDistinct(String s) {
        int len = s.length();
        if (len < 3){
            return len;
        }
        char[] words = s.toCharArray();
        char ch1 = words[0];
        int i = 1;
        while (i < len && words[i] == ch1){
            i++;
        }
        if (i == len){
            return len;
        }
        int same = 1;
        char preCh = words[i];
        int ans = i + 1;
        int result = ans;
        i++;
        while (i < len){
            if (words[i] == preCh){
                result++;
                same++;
            } else if (words[i] == ch1){
                result++;
                same = 1;
                ch1 = preCh;
                preCh = words[i];
            } else {
                ch1 = preCh;
                preCh = words[i];
                ans = Math.max(ans, result);
                result = same + 1;
                same = 1;
            }
            i++;
        }
        ans = Math.max(ans, result);
        return ans;
    }
}