题目
难度:★★☆☆☆
类型:字符串
你将得到一个字符串数组 A。
如果经过任意次数的移动,S == T,那么两个字符串 S 和 T 是特殊等价的。
一次移动包括选择两个索引 i 和 j,且 i % 2 == j % 2,交换 S[j] 和 S [i]。
现在规定,A 中的特殊等价字符串组是 A 的非空子集 S,这样不在 S 中的任何字符串与 S 中的任何字符串都不是特殊等价的。
返回 A 中特殊等价字符串组的数量。
提示
1 <= A.length <= 1000
1 <= A[i].length <= 20
所有 A[i] 都具有相同的长度。
所有 A[i] 都只由小写字母组成。
示例
示例 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"]
解答
特殊等价字符串具有相同的表示,我们要做的是寻找这种表示方式。
我们首先考虑这样一种情况,如果题目中没有奇偶位的限制,我们仅需统计所有字符出现的次数,即可判断两个字符串是否特殊等价(Counter(s1)==Counter(s2)),这时,相当于准备一个向量,这个向量有26个数字,每个数字代表相应字母出现次数,我们用这个计数器向量去表示字符串,只要两个字符串对应的计数器向量相等,那么这两个字符串等价;
但是,加上奇偶位的限制后,在奇数位上的字符,与在偶数位上的字符不能相互交换,相当于奇数位和偶数位上的相同字符也要区别对待,这样,我们将上述的26维向量加倍到52维,左右两半部分分别代表奇数位上所有字符的统计结果和偶数位上字符的统计结果,我们暂且称之为52维计数器向量,这个向量其实就成为了特殊等价字符串的表示向量,通过判断字符串对应的52维计数器向量是否相等,即可判断两个字符串是否是特殊等价的。
对于多个字符串,我们要获得其中一共有多少特殊等价字符串组,可以通过判断所有字符串对应的52维计数器向量中有多少不同类型即可。
class Solution(object):
def numSpecialEquivGroups(self, A):
def count(A):
c = [0] * 52
for i, letter in enumerate(A):
c[ord(letter) - ord('a') + 26 * (i % 2)] += 1
return tuple(c)
return len({count(word) for word in A})
如有疑问或建议,欢迎评论区留言~