1. 程式人生 > >Leetcode 字元串同構

Leetcode 字元串同構

今天用C#刷Leetcode,遇到字元串同構的題目,在網上看到兩種解法,第一種涉及到了c#中字典泛型,第二種用到了StringBuilder類,當在迴圈中將字串連在一起時,可以提升效能,各具特色,故分享之。

Question:Two words are called isomorphic if the letters in one word can be remapped to get the second word. Remapping a letter means replacing all occurrences of it with another letter while the ordering of the letters remains unchanged. No two letters may map to the same letter, but a letter may map to itself.

Example:
Given “foo”, “app”; returns true
we can map ‘f’ -> ‘a’ and ‘o’ -> ‘p’

Given “bar”, “foo”; returns false
we can’t map both ‘a’ and ‘r’ to ‘o’

Given “turtle”, “tletur”; returns true
we can map ‘t’ -> ‘t’, ‘u’ -> ‘l’, ‘r’ -> ‘e’, ‘l’ -> ‘u’, ‘e’ -‘r’

Given “ab”, “ca”; returns true
we can map ‘a’ -> ‘c’, ‘b’ -> ‘a’

Solution 1: from the description,  we need to make the mapping 1:1. to make sure it is 1:1 relationship, we can use two hash map to implement it, one for the first string, and another is for the second string.

        public bool isomorphic(string str1, string str2)
        {
            if (str1.Length != str2.Length)
            {
                return false;
            }

            var str1Dictionary = new Dictionary<char, char>();
            var str2Dictionary = new Dictionary<char, char>();
            var length = str1.Length;

            for (int i = 0; i < length; i++)
            {
                if (str1Dictionary.ContainsKey(str1[i]))
                {
                    if (str1Dictionary[str1[i]] != str2[i])
                    {
                        return false;
                    }
                }
                else
                {
                    str1Dictionary.Add(str1[i], str2[i]);
                }

                if (str2Dictionary.ContainsKey(str2[i]))
                {
                    if (str2Dictionary[str2[i]] != str1[i])
                    {
                        return false;
                    }
                }
                else
                {
                    str2Dictionary.Add(str2[i], str1[i]);
                }
            }

            return true;
        }

Solution 2: can we reduce the number of hash table to only 1? think this question in another way. We do not care about the char in string, the only thing we care is the char mapping to another char should always the same. if we can change the string to some number, which stands for its index, so that we know which it is. then all we need to do is compare two index array.

E.g. Foo and app both encode to 011
Abcd and hole both encode to 0123

Hate and hell do not match
As encodings are 0123 and 0122

        public bool isomorphic2(string str1, string str2)
        {
            if (str1.Length != str2.Length)
            {
                return false;
            }

            var strDictionary = new Dictionary<char, char>();
            var length = str1.Length;
            var stringbuilder1 = new StringBuilder();
            var stringbuilder2 = new StringBuilder();

            for (int i = 0; i < length; i++)
            {
                if (strDictionary.ContainsKey(str1[i]))
                {
                    stringbuilder1.Append(strDictionary[str1[i]]);
                }
                else
                {
                    strDictionary.Add(str1[i], Convert.ToChar(i));
                    stringbuilder1.Append(Convert.ToChar(i));
                }
            }

            strDictionary.Clear();
            for (int i = 0; i < length; i++)
            {
                if (strDictionary.ContainsKey(str2[i]))
                {
                    stringbuilder2.Append(strDictionary[str2[i]]);
                }
                else
                {
                    strDictionary.Add(str2[i], Convert.ToChar(i));
                    stringbuilder2.Append(Convert.ToChar(i));
                }
            }

            return stringbuilder1.ToString() == stringbuilder2.ToString();
        }