题目: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 }