You are given an array A
of strings.
A move onto S
consists of swapping any two even indexed characters of S
, or any two odd indexed characters of S
.
Two strings S
and T
are special-equivalent if after any number of moves onto S
, S == T
.
For example, S = "zzxy"
and T = "xyzz"
are special-equivalent because we may make the moves "zzxy" -> "xzzy" -> "xyzz"
that swap S[0]
and S[2]
, then S[1]
and S[3]
.
Now, a group of special-equivalent strings from A
is a non-empty subset of A such that:
- Every pair of strings in the group are special equivalent, and;
- The group is the largest size possible (ie., there isn't a string S not in the group such that S is special equivalent to every string in the group)
Return the number of groups of special-equivalent strings from A
.
Example 1:
Input: ["abcd","cdab","cbad","xyzz","zzxy","zzyx"] Output: 3 Explanation: One group is ["abcd", "cdab", "cbad"], since they are all pairwise special equivalent, and none of the other strings are all pairwise special equivalent to these. The other two groups are ["xyzz", "zzxy"] and ["zzyx"]. Note that in particular, "zzxy" is not special equivalent to "zzyx".
Example 2:
Input: ["abc","acb","bac","bca","cab","cba"] Output: 3
Note:
1 <= A.length <= 1000
1 <= A[i].length <= 20
- All
A[i]
have the same length. - All
A[i]
consist of only lowercase letters.
我觉得这个题目蛮好的,至少是一类题目的思路。
关键在于理清楚,一个字符串的偶数位和奇数位分别一样,不管位置如何,就可以是equivalent。
因此,万宗归一,对每个字符串s,奇数和偶数分别拎出来,只要其从小到大排列后,再合成字符串ss,对于所有equivalent的字符串,其归一后的ss是一样的。
用了std::map,归一后的字符串ss为key,原始做value。
代码如下,
class Solution {
public:
int numSpecialEquivGroups(vector<string>& A) {
std::map<string, vector<string>> res;
if(A.size() == 0)
return 0;
for(auto s : A)
{
vector<char> charEven;
vector<char> charOdd;
for(int i = 0; i < s.size(); i++)
{
if(i & 1)
{
charOdd.push_back(s[i]);
}
else
{
charEven.push_back(s[i]);
}
}
if(charEven.size() >0)
std::sort(charEven.begin(), charEven.end());
if(charOdd.size() >0)
std::sort(charOdd.begin(), charOdd.end());
string ss;
int i = 0;
for(i = 0; i < charEven.size() and i < charOdd.size(); i++)
{
ss.append(1, charEven[i]);
ss.append(1, charOdd[i]);
}
if(i < charEven.size())
ss.append(1, charEven[i]);
if(i < charOdd.size())
ss.append(1, charOdd[i]);
if(res.find(ss) != res.end())
res[ss].push_back(s);
else
res[ss] = vector<string>{s};
}
return res.size();
}
};
执行效果
Runtime: 32 ms, faster than 15.56% of C++ online submissions for Groups of Special-Equivalent Strings.
Memory Usage: 11.4 MB, less than 50.00% of C++ online submissions forGroups of Special-Equivalent Strings.
还凑合,不是吗?
看看别人的改进,其中一个思路是不重新合并新的ss,而是用vector<char> odd(26, 0)和vector<char> even(26,0),将奇偶位置上的字符串分别映射过去,作为key,直接copy一下别人的代码吧,侵权告知啦。
class Solution {
public:
int numSpecialEquivGroups(vector<string>& A) {
map<pair<vector<int>,vector<int>>,vector<string>>m;
int n = A.size();
for(int i=0;i<n;i++){
vector<int>even(26,0);
vector<int>odd(26,0);
for(int j=0;j<A[i].length();j++){
if(j%2==0)
even[A[i][j]-'a']++;
else
odd[A[i][j]-'a']++;
}
m[{even,odd}].push_back(A[i]);
}
return m.size();
}
};