题目:
你将得到一个字符串数组 A。
如果经过任意次数的移动,S == T,那么两个字符串 S 和 T 是特殊等价的。
一次移动包括选择两个索引 i 和 j,且 i % 2 == j % 2,交换 S[j] 和 S [i]。
现在规定,A 中的特殊等价字符串组是 A 的非空子集 S,这样不在 S 中的任何字符串与 S 中的任何字符串都不是特殊等价的。
返回 A 中特殊等价字符串组的数量。
解法一:
思路:
对每一个字符串分别进行奇偶位排序,然后利用set集合去重,set的size就是集合个数,因为特殊等价的字符串数组中,奇偶位排序结果是相同的
时间:
27 ms,多次使用排序,时间复杂度高
代码:
class Solution {
public int numSpecialEquivGroups(String[] A) {
Set<String> set=new HashSet<>();
StringBuilder sb=new StringBuilder();
for(String str:A){
String a="";
String b="";
for(int i=0;i<str.length();i++){
if(i%2==0){
a+=str.charAt(i);
}else{
b+=str.charAt(i);
}
}
a=sortString(a);
b=sortString(b);
set.add(a+b);
}
return set.size();
}
public static String sortString(String inputString)
{
char tempArray[] = inputString.toCharArray();
Arrays.sort(tempArray);
return new String(tempArray);
}
}
解法二:
思路(leetcode优解):
建立一个数组,每一位都是一个质数,奇数位和偶数位分别乘以不同的质数,得到的结果去重,因为质数不可分,所以不同的质数相乘结果不会相同,也就省去了排序这一过程
时间:
6 ms
代码:
class Solution {
private int[] dic = new int[]{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101};
public int numSpecialEquivGroups(String[] A) {
Set<Integer> set = new HashSet<>();
for (String s : A) {
set.add(hash(s));
}
return set.size();
}
private int hash(String s){
int edd = 1;
int even = 1;
boolean flag = true;
for (char c : s.toCharArray()) {
if (flag){
even *= dic[c - 'a'];
}else {
edd *= dic[c - 'a'];
}
flag = !flag;
}
return (edd + 50000) * even;
}
}