You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
2.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2022_11_3_week;
import java.util.HashMap;
// 来自亚马逊
// 给定一个字符串数组strs其中每个字符串都是小写字母组成的
// 如果i < j并且strs[i]和strs[j]所有的字符随意去排列能组成回文串
// 那么说(i,j)叫做一个互补对(complementary)
// 求strs中有多少个互补对
// strs长度 <= 3 * 10^5
// 单个字符串长度 <= 10^5
// strs里所有字符串总长度 <= 10^6
public class Code01_ComplementaryPairsInStringArray {
// 暴力方法
// 为了测试
public static int num1(String[] strs) {
int ans = 0;
for (int i = 0; i < strs.length; i++) {
for (int j = i + 1; j < strs.length; j++) {
if (complementary(strs[i], strs[j])) {
ans++;
}
}
}
return ans;
}
public static boolean complementary(String a, String b) {
int[] cnt = new int[26];
for (int i = 0; i < a.length(); i++) {
cnt[a.charAt(i) - 'a']++;
}
for (int i = 0; i < b.length(); i++) {
cnt[b.charAt(i) - 'a']++;
}
int odd = 0;
for (int num : cnt) {
if ((num & 1) != 0) {
odd++;
}
}
return odd < 2;
}
// 正式方法
// O(N*M)N字符串长M字符串平均长度
// 时间复杂度O(N) + O(M)一共有多少个字符串N一共有多少字符M
public static int num2(String[] strs) {
// key : 某一种状态(int类型状态)
// z..d c b a
// 3 2 1 0
// 1 0 1 1
// value : 这样状态的字符串,有几个
HashMap<Integer, Integer> status = new HashMap<>();
int ans = 0;
for (String str : strs) {
// 当前str这个字符串
// 它自己的状态,加工好
// d c b a
// 0 0 0 1
int cur = 0;
for (int i = 0; i < str.length(); i++) {
cur ^= 1 << (str.charAt(i) - 'a');
}
// 一点点都不捣乱curmap有几个状态也是cur的字符串
ans += status.getOrDefault(cur, 0);
for (int i = 0; i < 26; i++) {
// 每一位捣乱一下
// a
// b
// c
// z
ans += status.getOrDefault(cur ^ (1 << i), 0);
}
status.put(cur, status.getOrDefault(cur, 0) + 1);
}
return ans;
}
// 为了验证
public static String[] randomStringArray(int n, int m, int r) {
String[] ans = new String[n];
for (int i = 0; i < n; i++) {
int len = (int) (Math.random() * m) + 1;
char[] str = new char[len];
for (int j = 0; j < len; j++) {
str[j] = (char) ((int) (Math.random() * r) + 'a');
}
ans[i] = String.valueOf(str);
}
return ans;
}
public static void main(String[] args) {
int N = 100;
int M = 20;
int R = 5;
int testTime = 5000;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
int n = (int) (Math.random() * N) + 1;
String[] strs = randomStringArray(n, M, R);
int ans1 = num1(strs);
int ans2 = num2(strs);
if (ans1 != ans2) {
System.out.println("出错了!");
}
}
System.out.println("测试结束");
}
}