LeetCode //C - 49. Group Anagrams

49. Group Anagrams

Given an array of strings strs, group the anagrams together. You can return the answer in any order.

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
 

Example 1:

Input: strs = [“eat”,“tea”,“tan”,“ate”,“nat”,“bat”]
Output: [[“bat”],[“nat”,“tan”],[“ate”,“eat”,“tea”]]

Example 2:

Input: strs = [“”]
Output: [[“”]]

Example 3:

Input: strs = [“a”]
Output: [[“a”]]

Constraints:

  • 1 < = s t r s . l e n g t h < = 1 0 4 1 <= strs.length <= 10^4 1<=strs.length<=104
  • 0 <= strs[i].length <= 100
  • strs[i] consists of lowercase English letters.

From: LeetCode
Link: 49. Group Anagrams


Solution:

Ideas:

The goal is to group anagrams from a given list of strings. Anagrams are words or phrases formed by rearranging the letters of a different word or phrase.

Main Components:

  1. Sorting Strings: Since anagrams have the same characters, just arranged in a different order, we can identify anagrams by sorting their characters. If two words are anagrams, their sorted forms will be identical.

  2. Hash Table: We use a hash table to store the groups of anagrams. The key is the sorted form of the string, and the value is a list of original strings that are anagrams of that sorted string.

  3. Collision Handling with Linked List: Since multiple keys may hash to the same index in the table (collision), we handle this by using a linked list for each table index. Each node in the linked list contains:

  • sortedStr: The sorted form of the string (key).
  • anagrams: A dynamic array of original strings that are anagrams of the sorted string.
  • count: The number of anagrams in the group.
  • capacity: The capacity of the dynamic array.
  • next: Pointer to the next node in the linked list.
  1. Hash Function: We define a simple hash function to convert a sorted string into an index in the hash table.

  2. Insertion and Grouping Logic:

  • For each original string, sort it and compute its hash value.
  • Check if the sorted string already exists in the hash table.
  • If it does, add the original string to the existing anagram group.
  • If not, create a new node and add it to the hash table.
  1. Collecting Result: Finally, we traverse the hash table and collect all the anagram groups to form the result.
Code:
/**
 * 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().
 */
 
// Function to compare characters for sorting
int compare(const void *a, const void *b) {
    return *(const char *)a - *(const char *)b;
}

// Structure to represent each hash table node
typedef struct Node {
    char *sortedStr;
    char **anagrams;
    int count;
    int capacity;
    struct Node *next;
} Node;

// Function to create a new hash table node
Node *newNode(char *sortedStr, char *originalStr) {
    Node *node = (Node *)malloc(sizeof(Node));
    node->sortedStr = sortedStr;
    node->anagrams = (char **)malloc(sizeof(char *) * 2);
    node->anagrams[0] = originalStr;
    node->count = 1;
    node->capacity = 2;
    node->next = NULL;
    return node;
}

// Hash function
unsigned int hash(char *str) {
    unsigned int hashValue = 0;
    while (*str) {
        hashValue = (hashValue * 31) + *str;
        str++;
    }
    return hashValue;
}

#define TABLE_SIZE 5000

char ***groupAnagrams(char **strs, int strsSize, int *returnSize, int **returnColumnSizes) {
    Node *table[TABLE_SIZE] = {0};

    for (int i = 0; i < strsSize; ++i) {
        // Sort current string
        char *sortedStr = strdup(strs[i]);
        qsort(sortedStr, strlen(sortedStr), sizeof(char), compare);

        // Compute hash value
        unsigned int idx = hash(sortedStr) % TABLE_SIZE;

        // Look for anagram group
        Node *current = table[idx];
        while (current != NULL && strcmp(sortedStr, current->sortedStr) != 0) {
            current = current->next;
        }

        if (current == NULL) { // New anagram group
            Node *node = newNode(sortedStr, strs[i]);
            node->next = table[idx];
            table[idx] = node;
        } else { // Existing anagram group
            if (current->count == current->capacity) {
                current->capacity *= 2;
                current->anagrams = (char **)realloc(current->anagrams, sizeof(char *) * current->capacity);
            }
            current->anagrams[current->count++] = strs[i];
            free(sortedStr);
        }
    }

    // Collect result
    char ***result = (char ***)malloc(sizeof(char **) * strsSize);
    *returnColumnSizes = (int *)malloc(sizeof(int) * strsSize);
    *returnSize = 0;
    for (int i = 0; i < TABLE_SIZE; ++i) {
        Node *current = table[i];
        while (current != NULL) {
            result[*returnSize] = current->anagrams;
            (*returnColumnSizes)[*returnSize] = current->count;
            (*returnSize)++;
            Node *temp = current;
            current = current->next;
            free(temp->sortedStr);
            free(temp);
        }
    }

    return result;
}

你可能感兴趣的:(LeetCode,leetcode,c语言,算法)