题目:Group Anagrams
将字符串数组分组,变位词组为一组
变位词:单词的字母相同位置不同
思路1:
暴力搜索,比较每个单词。
/*************************************************************************************************** Given an array of strings, group anagrams together. For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], Return: [ ["ate", "eat","tea"], ["nat","tan"], ["bat"] ] Note: All inputs will be in lower-case. ***************************************************************************************************/ #include<stdio.h> /***不通过,时间超过了**/ int checkEquation(char *str1,char *str2){//判断是否为变位词 int alphabets[26] = {0}; //遍历第一个字符串 for(int i = 0;i < strlen(str1);i++){//对应字母的下标加一 alphabets[str1[i] - 'a']++; } for(int i = 0;i < strlen(str2);i++){//对应字母的下标减一 alphabets[str2[i] - 'a']--; } for(int i = 0;i < 26;i++){//是变位词,数组所有元素都应该归零 if(alphabets[i] > 0)return 1; else if(alphabets[i] < 0)return -1; } return 0; } /** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *columnSizes array. * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). */ char*** groupAnagrams(char** strs, int strsSize, int** columnSizes, int* returnSize) { int length = 0,i,j,pre = 0; int *groupId = (int *)malloc(strsSize*sizeof(int));//记录相同组的ID,类似链表的形式连接 int *groupLen = (int *)malloc(strsSize*sizeof(int));//记录每组单词数量 memset(groupId,0,strsSize*sizeof(int)); memset(groupLen,-1,strsSize*sizeof(int)); for(i = 0;i < strsSize;i++){ if(groupId[i] != 0)continue; pre = i; groupLen[i] = 1; for(j = i + 1;j < strsSize;j++){ if(checkEquation(strs[i],strs[j]) == 0){ groupLen[i]++; groupId[pre] = j; pre = j; } } groupId[pre] = -1; length++; } } char ***retStrs = (char ***)malloc(length*sizeof(char **)); int *columnsLen = (int *)malloc(length*sizeof(int)); int index = 0,k; for(i = 0;i < strsSize;i++){//转化为字符数组输出 if(groupLen[i] == -1)continue; columnsLen[index] = groupLen[i]; retStrs[index] = (char **)malloc(columnsLen[index]*sizeof(char *)); j = i; k = 0; while(groupId[j] != -1){ retStrs[index][k] = (char *)malloc((strlen(strs[j]) + 1)*sizeof(char)); strcpy(retStrs[index][k++],strs[j]); j = groupId[j]; } retStrs[index][k] = (char *)malloc((strlen(strs[j]) + 1)*sizeof(char)); strcpy(retStrs[index][k],strs[j]); index++; } *columnSizes = columnsLen; *returnSize = length; free(groupId); free(groupLen); return retStrs; }
思路2:
排序,我讲每个单词的字母之和作为值去比较,排序;
同时排序时把变位词放在一起,保证相邻的单词必定为变位词
1 /*************************************************************************************************** 2 Given an array of strings, group anagrams together. 3 For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], 4 Return: 5 [ 6 ["ate", "eat","tea"], 7 ["nat","tan"], 8 ["bat"] 9 ] 10 Note: All inputs will be in lower-case. 11 ***************************************************************************************************/ 12 #include<stdio.h> 13 14 struct CharArray{ 15 int length;//字符串长度 16 int value;//每个单词的值之和 17 char *str; 18 }; 19 20 int checkEquation(struct CharArray *cas1,struct CharArray *cas2){ 21 int alphabets[26] = {0}; 22 for(int i = 0;i < cas1->length;i++){ 23 alphabets[cas1->str[i] - 'a']++; 24 } 25 for(int i = 0;i < cas2->length;i++){ 26 alphabets[cas2->str[i] - 'a']--; 27 } 28 for(int i = 0;i < 26;i++){ 29 if(alphabets[i] > 0)return 1; 30 else if(alphabets[i] < 0)return -1; 31 } 32 return 0; 33 } 34 35 int cmp(const void *a , const void *b){ 36 struct CharArray *cas1 = (struct CharArray *)a; 37 struct CharArray *cas2 = (struct CharArray *)b; 38 int value = 0; 39 for(int i = 0;i < cas1->length;i++){//先按字母值得和比较排除大部分情况。 40 value += cas1->str[i] - 'a' + 1; 41 } 42 cas1->value = value; 43 for(int i = 0;i < cas2->length;i++){ 44 value -= cas2->str[i] - 'a' + 1; 45 } 46 cas2->value = cas1->value - value; 47 if(value != 0)return value; 48 return checkEquation(cas1,cas2);//比较是否为变位词 49 } 50 51 /** 52 * Return an array of arrays of size *returnSize. 53 * The sizes of the arrays are returned as *columnSizes array. 54 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). 55 */ 56 char*** groupAnagrams(char** strs, int strsSize, int** columnSizes, int* returnSize) { 57 struct CharArray *cas = (struct CharArray *)malloc(strsSize*sizeof(struct CharArray)); 58 for(int i = 0;i < strsSize;i++){ 59 cas[i].str = strs[i]; 60 cas[i].length = strlen(strs[i]); 61 } 62 63 qsort(cas,strsSize,sizeof(struct CharArray),cmp); 64 65 int length = 0,i,j,count = 0; 66 int *divideLen = (int *)malloc((strsSize + 1)*sizeof(int)); 67 memset(divideLen,-1,(strsSize + 1)*sizeof(int)); 68 for(i = 0;i < strsSize;i++){ 69 divideLen[length++] = i; 70 while(i < strsSize - 1 && cas[i].value == cas[i + 1].value){//查找变位词 71 if(checkEquation(&cas[i],&cas[i + 1]) != 0)break;//不是则跳出 72 i++; 73 } 74 } 75 divideLen[length] = strsSize; 76 77 char ***retStrs = (char ***)malloc(length*sizeof(char **)); 78 int *columnsLen = (int *)malloc(length*sizeof(int)); 79 for(i = 1;i <= length;i++){ 80 columnsLen[i - 1] = divideLen[i] - divideLen[i - 1]; 81 retStrs[i - 1] = (char **)malloc(columnsLen[i - 1]*sizeof(char *)); 82 for(j = 0;j < columnsLen[i - 1];j++){ 83 retStrs[i - 1][j] = (char *)malloc((cas[count].length + 1)*sizeof(char)); 84 strcpy(retStrs[i - 1][j],cas[count++].str); 85 } 86 } 87 88 free(divideLen); 89 free(cas); 90 *columnSizes = columnsLen; 91 *returnSize = length; 92 return retStrs; 93 }