893. Groups of Special-Equivalent Strings(特殊等价字符串组)
程序员文章站
2022-04-02 21:27:55
...
893. 特殊等价字符串组
你将得到一个字符串数组
A
。如果经过任意次数的移动,S == T,那么两个字符串
S
和T
是特殊等价的。一次移动包括选择两个索引
i
和j
,且i % 2 == j % 2
,交换S[j]
和S [i]
。现在规定,
A
中的特殊等价字符串组是A
的非空子集S
,这样不在S
中的任何字符串与S
中的任何字符串都不是特殊等价的。返回
A
中特殊等价字符串组的数量。
示例 1:
输入:["a","b","c","a","c","c"] 输出:3 解释:3 组 ["a","a"],["b"],["c","c","c"]示例 2:
输入:["aa","bb","ab","ba"] 输出:4 解释:4 组 ["aa"],["bb"],["ab"],["ba"]示例 3:
输入:["abc","acb","bac","bca","cab","cba"] 输出:3 解释:3 组 ["abc","cba"],["acb","bca"],["bac","cab"]示例 4:
输入:["abcd","cdab","adcb","cbad"] 输出:1 解释:1 组 ["abcd","cdab","adcb","cbad"]
提示:
1 <= A.length <= 1000
1 <= A[i].length <= 20
- 所有
A[i]
都具有相同的长度。- 所有
A[i]
都只由小写字母组成。
解法一
//时间复杂度O(m*n), 空间复杂度O(m), m是字符串长度, n是字符串数组长度
class Solution {
public:
int numSpecialEquivGroups(vector<string>& A) {
unordered_set<string> us;
for(string str : A) {
string mark(52, '0');//计数:奇a-z偶a-z
bool odd = true;
for(char c : str) {
if(odd) mark[c - 'a']++;
else mark[26 + (c - 'a')]++;
odd = !odd;
}
us.insert(mark);
}
return us.size();
}
};
思路:
这个题目描述比较晦涩,大体意思可以这么表述:(题目上叫“特殊等价字符串”,简单点就叫它“等价字符串”吧)
等价字符串:奇数和偶数位上的字母出现次数分别一致的两个字符串。比如abcd和cdba,这两个字符串的奇数位上字母为a、c,偶数位上为b、d,出现次数都是1,所以它俩是等价字符串。
等价字符串数组:在字符串数组A中,所有互为等价字符串的字符串的集合。
理解了题意之后,思路就很明显了,我们要遍历A中的每一个字符串str,对每一个字符串都维护一个哈希表对(um1, um2):
unordered_map<char, int> um1, um2,
um1存储奇数位上的字母计数,um2存储偶数位上的字母计数。对于等价字符串,其哈希表对是相等的。题目要求的输出就是等价字符串集合个数,也就是对于所有的不重复的哈希表对(um1, um2)的个数。
解法一
按上述思路走就可以解出来了,但是维护这么多哈希表有些繁琐,解法一采用了将哈希表对映射成字符串,这样就可以使用内置的unordered_set进行去重,最后直接返回其大小。
另外的思路,可以将每个字符串的奇偶位分别排序,直接放入unordered_set中,虽然排序是个耗时操作,但是题上说字符串最长为20,其实效率也是不错的。
2019/07/30 22:47