Leetcode 49. Group Anagrams

该博客介绍了一种使用C语言实现的字母排序分组算法,通过快速排序将单词字符按升序排列作为键,用于将具有相同字符顺序的单词归为一类。博客内容包括了数据结构定义、排序及分组函数,适用于LeetCode中49题‘分组字母异位词’的问题。
摘要由CSDN通过智能技术生成

看到的一个比较好的解法:

#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)

https://bitbucket.org/msreekan/algorithms-and-data-structures/src/04a9d18465f2b9c8b4cf51476128c3f6ada5f36a/Strings/49.GroupAnagrams/GroupAnagrams.c?at=master

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值