解题思路:
1、开始阶段使用暴力解法,通过将A/B字符中中的’a’~‘z’ 26个字符的数量统计出来,然后计算A中的每个字符串是否大于B中的每个字符串的长度。
2、优化算法:BNum[BSize][MAX_COL] 计算每一列的最大的长度,然后把A中的每个字符串与最大长度比较,是否满足ANum[ASize][MAX_COL] > maxOfCol[MAX_COL],如果全部满足,可以认为是满足条件的。只要有一个不满足,则不满足这个条件。
https://leetcode-cn.com/problems/word-subsets/
我们给出两个单词数组 A 和 B。每个单词都是一串小写字母。
现在,如果 b 中的每个字母都出现在 a 中,包括重复出现的字母,那么称单词 b 是单词 a 的子集。 例如,“wrr” 是 “warrior” 的子集,但不是 “world” 的子集。
如果对 B 中的每一个单词 b,b 都是 a 的子集,那么我们称 A 中的单词 a 是通用的。
你可以按任意顺序以列表形式返回 A 中所有的通用单词。
#define MAX_LEN 11
#define MAX_COL 26
#define MAX(a,b) (a) > (b) ? (a) : (b)
char ** wordSubsets(char ** A, int ASize, char ** B, int BSize, int* returnSize){
int **BNum = (int **) malloc (BSize * sizeof(int *));
for (int i = 0; i < BSize; i++){
BNum[i] = (int *) malloc (26 * sizeof(int));
memset(BNum[i], 0, 26 * sizeof(int));
int len = strlen(B[i]);
for (int j = 0; j < len; j++){
BNum[i][B[i][j] - 'a']++;
}
}
int maxOfCol[MAX_COL] = {0};
for (int j = 0; j < MAX_COL; j++){
int maxj = 0;
for (int i = 0; i < BSize; i++){
maxj = MAX (maxj, BNum[i][j]);
maxOfCol[j] = maxj;
}
}
char **res = (char **) malloc(ASize * sizeof(char*));
*returnSize = 0;
int **ANum = (int **) malloc (ASize * sizeof(int *));
for (int i = 0; i < ASize; i++){
ANum[i] = (int *) malloc (26 * sizeof(int));
memset(ANum[i], 0, 26 * sizeof(int));
int len = strlen(A[i]);
for (int j = 0; j < len; j++){
ANum[i][A[i][j] - 'a']++;
}
int flag = 1;
for (int j = 0; j < MAX_COL; j++){
if(ANum[i][j] < maxOfCol[j]){
flag = 0;
break;
}
}
if(flag == 1){
res[*returnSize] = (char *) malloc (MAX_LEN * sizeof(char));
memset(res[*returnSize], 0, MAX_LEN);
strcpy (res[*returnSize], A[i]);
(*returnSize)++;
}
}
return res;
}