题目链接:https://leetcode.com/problems/valid-anagram/
题目内容:
Given two strings s and t, write a function to determine if t is an anagram of s.
For example,
s = "anagram", t = "nagaram", return true.
s = "rat", t = "car", return false.
Note:
You may assume the string contains only lowercase alphabets.
Follow up:
What if the inputs contain unicode characters? How would you adapt your solution to such case?
题目分析:
最容易想到的方法就是排序,然后比较两个string是否一样,不过一般排序的代价都比较昂贵,即使测试用例不大,但是本着要找到O(n)或者更快的作死态度,不想用这种。后来是想到一种比较取巧的方法,数学的方法,比如分别将各个字符的ASCIi码加起来,比较两个总和是否一样,然而测试用例早已看穿一切,比如给个“ac” 和“bb”;那就换个,比如将ascii码的平方加起来,测试用例用两串完全不搭边的字符串给了我哥wa,哎运气不好~的确这种没有严格数学证明的转换,即使你找到一个很好的转换(比如ac后我去讨论区看到一个童鞋就用ascii乘上素数的转换),AC了所有测试用例,也不代表完美,比如上面提到的用素数转换,另一位细心的网友就找出特例否定了他。看来只能用另一种更加容易想到的方法了,分别统计两个string中各个字符的个数,对比两个统计结果数组,一样的话返回真。一开始想到要用能保存key-value这种类型的结构类型就懒得去用这个办法,比如map。后来去上个厕所突然灵机一动,直接用个26元素的数组保存就可以了,不用保存key,或者说数组下标本身就能完成一种映射,比如下标0代表'a',1代表‘b’,以此类推。下面就是ac的代码了,可惜还是用了12ms(>o<)
class Solution { public: bool isAnagram(string s, string t) { if(s == t) return true; else if(s.size() != t.size()) return false; else{ int sarr[26] = {0}; int tarr[26] = {0}; int len = s.size(); for(int i=0; i < len; i++) { sarr[s[i] - 'a']++; tarr[t[i] - 'a']++; } for(int i = 0; i < 26; i++) if(sarr[i] != tarr[i]) return false; return true; } } };
class Solution { public: bool isAnagram(string s, string t) { if(s.length() != t.length()) return false; int count[26] = {0}; for(int i=0;i<s.length();i++) { count[s[i]-'a']++; count[t[i]-'a']--; } for(int i=0;i<26;i++) if(count[i] != 0) return false; return true; } };