题目描述
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:
输入: strs = [""]
输出: [[""]]
示例 3:
输入: strs = ["a"]
输出: [["a"]]
提示:
1 <= strs.length <= 10^4
0 <= strs[i].length <= 100
strs[i]
仅包含小写字母
题解
/**
* 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().
*/
#define STR_SIZE 101
// Define a structure for the hash node
typedef struct Node {
char str[STR_SIZE]; // Key is the string
int row; // Value is the row where the result is located
struct Node *next;
} HashNode;
// Function to calculate the hash value for a string
int hash(char *str, int size) {
long h = 0;
for (int i = 0; i < strlen(str); i++) {
h = (h * 26 % size + str[i] - 'a') % size; // String's hashcode, weight is 26 for lowercase letters
// Taking modulo to prevent integer overflow
}
return h % size;
}
// Function to check if a string is already in the hashtable
bool contain(HashNode *hashtable, char *str, int size) {
HashNode *head = &hashtable[hash(str, size)];
HashNode *tail = head->next;
while (tail) {
if (strcmp(tail->str, str) == 0) return true;
tail = tail->next;
}
return false;
}
// Function to add a string to the hashtable
void add(HashNode *hashtable, char *str, int size, int row) {
if (contain(hashtable, str, size)) return;
HashNode *head = &hashtable[hash(str, size)];
// Insert at the head of the linked list
HashNode *q = malloc(sizeof(HashNode));
strcpy(q->str, str);
q->row = row;
q->next = head->next;
head->next = q;
}
// Function to get the row of a string in the hashtable
int getRows(HashNode *hashtable, char *str, int size) {
HashNode *head = &hashtable[hash(str, size)];
HashNode *tail = head->next;
while (tail) {
if (strcmp(tail->str, str) == 0) return tail->row;
tail = tail->next;
}
return -1;
}
// Comparison function for qsort
int cmp(const void *a, const void *b) {
return *(char *)a - *(char *)b;
}
// Main function to group anagrams
char ***groupAnagrams(char **strs, int strsSize, int *retSize, int **columnSizes) {
if (strsSize == 0 || strs == NULL) {
*retSize = 0;
return NULL;
}
HashNode *hashtable = malloc(sizeof(HashNode) * strsSize);
memset(hashtable, 0, sizeof(HashNode) * strsSize);
char ***ans = malloc(sizeof(char **) * strsSize);
*retSize = 0;
*columnSizes = malloc(sizeof(int) * strsSize);
for (int i = 0; i < strsSize; i++) {
char curStr[STR_SIZE] = "";
strcpy(curStr, strs[i]);
int lenStr = strlen(curStr);
qsort(curStr, lenStr, sizeof(char), cmp); // Sort the string
if (contain(hashtable, curStr, strsSize)) { // Key already exists
int row = getRows(hashtable, curStr, strsSize); // Get the row where the key's result is located
int col = (*columnSizes)[row];
ans[row][col] = malloc(sizeof(char) * (lenStr + 1));
strcpy(ans[row][col], strs[i]);
(*columnSizes)[row]++;
} else { // Key does not exist
add(hashtable, curStr, strsSize, *retSize); // Insert into the hashtable
ans[*retSize] = malloc(sizeof(char *) * strsSize); // Allocate a new row
ans[*retSize][0] = malloc(sizeof(char) * (lenStr + 1));
strcpy(ans[*retSize][0], strs[i]);
(*columnSizes)[*retSize] = 1;
(*retSize)++;
}
}
return ans;
}