Two Strings Are Anagrams
- leetcode: Valid Anagram
- lintcode:
Write a method to decide if two strings are anagrams or not.
Clarification
What is Anagram?
- Two strings are anagram if they can be the same after change the order of
characters.
Given s = "abcd"
, t = "dcab"
, return true
.
Given s = "ab"
, t = "ab"
, return true
.
Given s = "ab"
, t = "ac"
, return false
.
Challenge **
O(n) time, O(1) extra space
Python
C++
class Solution {
public:
/**
* @param s: The first string
* @param b: The second string
* @return true or false
*/
bool anagram(string s, string t) {
if (s.empty() || t.empty()) {
}
if (s.size() != t.size()) {
return false;
}
for (int i = 0; i != s.size(); ++i) {
++letterCount[s[i]];
--letterCount[t[i]];
}
for (int i = 0; i != t.size(); ++i) {
if (letterCount[t[i]] != 0) {
return false;
}
}
return true;
}
};
源码分析
- 两个字符串长度不等时必不可能为变位词(需要注意题目条件灵活处理)。
- 初始化含有256个字符的计数器数组。
- 对字符串 s 自增,字符串 t 递减,再次遍历判断
letterCount
数组的值,小于0时返回false
.
在字符串长度较长(大于所有可能的字符数)时,还可对第二个for
循环做进一步优化,即t.size() > 256
时,使用256替代t.size()
直接比较字符计数, 使用i
替代t[i]
.
复杂度分析
两次遍历字符串,时间复杂度最坏情况下为 O(n), 使用了额外的数组,空间复杂度 O(1).
另一直接的解法是对字符串先排序,若排序后的字符串内容相同,则其互为变位词。
class Solution:
"""
@param s: The first string
"""
def anagram(self, s, t):
return sorted(s) == sorted(t)
C++
Java
public class Solution {
/**
* @param s: The first string
* @param b: The second string
* @return true or false
*/
public boolean anagram(String s, String t) {
if (s == null || t == null) return false;
if (s.length() != t.length()) return false;
char[] sChars = s.toCharArray();
char[] tChars = t.toCharArray();
Arrays.sort(sChars);
Arrays.sort(tChars);
for (int i = 0; i != s.length(); i++) {
if (sChars[i] != tChars[i]) return false;
}
return true;
}
};
复杂度分析
C++的 STL 中 sort 的时间复杂度介于 O(n) 和 O(n^2)之间,判断时间复杂度最坏为 O(n). 可以看出此方法的时间复杂度相比题解1还是比较高的。Java 中字符串默认不可变,故空间复杂度为 O(n).