你将得到一个字符串数组 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] 都只由小写字母组成。
1 int numSpecialEquivGroups(char** A, int ASize) 2 { 3 int i, j, k, is_new_group = 1, group = 0; 4 int odd_index_sum[ASize]; //用来存放每一行字符串的奇位元素的平方的相加值,之所以平方是为了免去偶然性 5 int even_index_sum[ASize]; //用来存放每一行字符串的偶位元素的平方的相加值,之所以平方是为了免去偶然性 6 int string_len = strlen(A[0]); //由于每一行字符串的长度是固定的,所以只需要算出一个的长度即可 7 memset(odd_index_sum, 0, ASize * sizeof(int)); //初始化,数组清零 8 memset(even_index_sum, 0, ASize * sizeof(int)); 9 for(i = 0; i < ASize; i++) 10 { 11 is_new_group = 1; //is_new_group,判断是否有新的组产生,是就是1,不是就置为0,刚开始都置1 12 for(j = 1; j < string_len; j += 2) 13 { 14 odd_index_sum[i] += A[i][j] * A[i][j]; //奇位元素平方后相加 15 } 16 17 for(j = 0; j < string_len; j += 2) 18 { 19 even_index_sum[i] += A[i][j] * A[i][j]; //偶位元素平方后相加 20 } 21 22 for(k = 0; k < i; k++) 23 { 24 /*k从0开始到i,如果i前面出现了与自身i同组的元素,那就没必要再比下去,group也不必递增*/ 25 if(odd_index_sum[i] == odd_index_sum[k] && even_index_sum[i] == even_index_sum[k]) 26 { 27 is_new_group = 0; 28 break; 29 } 30 } 31 /*上面的k经过加加变成了i之后,还没遇到与i同组的元素,那么证明A[i]可以产生一个新的组*/ 32 if(1 == is_new_group) 33 { 34 group++; 35 } 36 } 37 return group; 38 }
解题思路:
题目中提到了一次移动包括选择两个索引 i
和 j
,且 i % 2 == j % 2
,交换 S[j]
和 S
[i]
。
即单个字符串中的 奇数 或者 偶数 位置上的字符可以随意调换,
通过计算每个字符串的,奇数 和 偶数 位置上的数值平方,来确定不同的字符串是否相等,
从而得到特殊等价字符串的数量。