49. 字母异位词分组
题目描述
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"]
输出:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
说明:
- 所有输入均为小写字母。
- 不考虑答案输出的顺序。
题解:
法一:
排序。对 strs
中的每个字符串排序,假设原串为 s
,排序后的串为 s'
,保存为 pair(s', s)
。
对整体的 pair
进行排序,排序后,字符组成相同的字符串会相邻在一起。所以直接遍历即可。
时间复杂度:
O
(
n
k
l
o
g
n
)
O(nklogn)
O(nklogn) ,n
是字符串个数,k
是字符串平均长度。
法一代码:
class Solution {
public:
using PSS = pair<string, string>;
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<PSS> ans;
for( auto& it : strs ) {
auto t = it;
sort( t.begin(), t.end() );
ans.push_back( {t, it} );
}
sort(ans.begin(), ans.end());
vector<vector<string>> ret;
vector<string> tmp;
tmp.push_back( move(ans[0].second) );
for ( int i = 1; i < ans.size(); ++i ) {
if ( ans[i].first == ans[i - 1].first )
tmp.push_back( move(ans[i].second) );
else {
ret.push_back( move(tmp) );
tmp.clear();
tmp.push_back( move(ans[i].second) );
}
}
if ( tmp.size() ) ret.push_back( move(tmp) );
return ret;
}
};
/*
时间:36ms,击败:99.13%
内存:18.8MB,击败:79.91%
*/
法二:
哈希。将组成字符相同的字符串映射成相同的 key
就可以了。
这里我直接将字符串排序,然后直接使用 unordered_map<string, vector<string>>
。
时间复杂度: O ( n k l o g k ) O(nklogk) O(nklogk)
法二代码:
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string, vector<string>> hash;
string ans;
for ( auto& it : strs ) {
ans = it;
sort( ans.begin(), ans.end() );
hash[ans].push_back(move( it ) );
}
vector<vector<string>> ret;
for( auto& it : hash )
ret.push_back(move( it.second ) );
return ret;
}
};
/*
时间:32ms,击败:99.66%
内存:17.9MB,击败:95.12%
*/