Leetcode 159 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.

Solution:

1. use Hashtable

hashtable来存字母和index 的pair。即时更新hashtable。

public int LengthOfLongestSubstringTwoDistinct(string s) {
        Dictionary<char,int> hashtable = new Dictionary<char,int>();
        int max = 0;
        int sum =0;
        for(int i =0;i< s.Length;i++)
        {
            if(hashtable.ContainsKey(s[i]))
            {
                sum++;
                hashtable[s[i]] = i;
            }
            else if(hashtable.Count()<2)
            {
                sum++;
                hashtable.Add(s[i],i);
            }
            else//need to exchange a charactersitic
            {
                var a = new List<char>();
                var b = new List<int>();
                foreach (var pair in hashtable)
                {
                    a.Add(pair.Key);
                    b.Add(pair.Value);
                }
                if(b[0]>b[1])
                {
                    sum = i-b[1];
                    hashtable.Remove(a[1]);
                }
                else
                {
                    sum = i-b[0];
                    hashtable.Remove(a[0]);
                }
                hashtable.Add(s[i],i);
            }
            max = Math.Max(max,sum);
        }
        return max;
    }

The hashtable Method is easy to extend to K Distince Characters. But we need to do a little change becasue we need to remove the element from Dictionary by value, so we can use Linq. Here is the changed code:

public int LengthOfLongestSubstringTwoDistinct(string s) {
        Dictionary<char,int> hashtable = new Dictionary<char,int>();
        int max = 0;
        int sum =0;
        for(int i =0;i< s.Length;i++)
        {
            if(hashtable.ContainsKey(s[i]))
            {
                sum++;
                hashtable[s[i]] = i;
            }
            else if(hashtable.Count()<2)
            {
                sum++;
                hashtable.Add(s[i],i);
            }
            else//need to exchange a charactersitic
            {
                int leftMost = Int32.MaxValue;
                foreach (var pair in hashtable)
                {
    
                    leftMost = Math.Min(leftMost, pair.Value);
                }
                sum = i-leftMost;
                var needRemove = hashtable.First(x => x.Value ==leftMost );
                hashtable.Remove(needRemove.Key);
                hashtable.Add(s[i],i);
            }
            max = Math.Max(max,sum);
        }
        return max;
    }

2. 2 pointer & sliding window

从网上看到的用sliding window来track 两个字母中左边的最右位, j用来track左边字母的最右位,如果出现字母与其左边临近字母不同,再检查是否是之前左边的字母,如果是,j赋新值;如果不是,则计算最大距离并用i代表substring的最左端。

 public int LengthOfLongestSubstringTwoDistinct(string s) {
        int i = 0, j = -1;
        int maxLen = 0;
        for (int k = 1; k < s.Length; k++) {
            if (s[k] == s[k-1]) continue;
            if (j > -1 && s[k] != s[j]) {
                maxLen = Math.Max(maxLen, k - i);
                i = j + 1;
            }
            j = k - 1;
        }
        return maxLen > (s.Length - i) ? maxLen : s.Length - i;
    }
原文地址:https://www.cnblogs.com/renyualbert/p/5786134.html