看到的一个比较好的解法:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*
Entry represents a word. The key is string you get after re-arranging the word charachters in ascending order. Value represents the word itself.
*/
typedef struct {
char* key;
char* value;
} Entry;
/*
Comparator for sorting charachters of a word
*/
int keyCmp(void* a, void*b){
return *((char*)a) - *((char*)b);
}
/*
Comparator for sorting an array of entries using the key
*/
int entryCmp(void*_a, void* _b){
Entry* a = (Entry*)_a;
Entry* b = (Entry*)_b;
return strcmp(a->key, b->key);
}
/*
List implementation
*/
typedef struct {
void** entries;
int count;
int capacity;
int unitSize;
} List;
List* initList(){
List* result = malloc(sizeof(List));
result->count = 0;
result->capacity = 10;
result->entries = malloc(sizeof(void**) * result->capacity);
return result;
}
void addItem(List* list, void* item){
if(list->count == list->capacity){
list->capacity *= 2;
list->entries = realloc(list->entries, list->capacity*sizeof(void**));
}
list->entries[list->count] = item;
list->count++;
}
/*
End of list implementation
*/
/**
Given a list of list of entries, return the last entry of last list.
**/
inline Entry* getLastEntry(List* groupedEntries){
return (Entry*)(((List*)(groupedEntries->entries[groupedEntries->count-1]))->entries[0]);
}
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
char *** groupAnagrams(char ** strs, int strsSize, int* returnSize, int** returnColumnSizes){
Entry entries[strsSize];
// populate entries array
for(int i = 0; i < strsSize; i++){
char*key = malloc((strlen(strs[i])+1) * sizeof(char));
strcpy(key, strs[i]);
// Key of an entry is word sorted in ascending order
qsort(key, strlen(key), sizeof(char), keyCmp);
entries[i] = (Entry){.key=key, .value=strs[i]};
}
// Sort the entries
qsort(entries, strsSize, sizeof(Entry), entryCmp);
//Now, grouping can be done easily since related keys are close-by
List*groupedEntries = initList();
for(int i = 0; i < strsSize; i++){
if(groupedEntries->count == 0|| strcmp(getLastEntry(groupedEntries)->key, entries[i].key) != 0){
// group is either empty or last added elements key doesn't match current entry key.
// Make a new group
List* newGroup = initList();
addItem(newGroup, &entries[i]);
addItem(groupedEntries,(void*) newGroup);
}
else{
// Last added element's key matches current element's key. So add to last group.
addItem((List*)(groupedEntries->entries[groupedEntries->count-1]), &entries[i]);
}
}
// Output preparations
*returnSize = groupedEntries->count;
char*** returnArray = malloc(groupedEntries->count * sizeof(char**));
int* columnSizes = malloc(sizeof(int) * groupedEntries->count);
*returnColumnSizes = columnSizes;
for(int i = 0; i < groupedEntries->count; i++){
List* groupEntries = (List*)(groupedEntries->entries[i]);
columnSizes[i] = groupEntries->count;
returnArray[i] = malloc(sizeof(char*) * groupEntries->count);
for(int j = 0; j < groupEntries->count; j++){
Entry* entry = (Entry*)(groupEntries->entries[j]);
returnArray[i][j] = entry->value;
}
}
return returnArray;
}
来源:
https://leetcode.com/problems/group-anagrams/discuss/1047545/A-C-solution-using-quick-sort-(100)