LeetCode 49字母异位词分组 C语言

7-12 LeetCode 49 字母异位词分组

题目

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

示例1:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

示例2:

输入: strs = [""]

输出: [[""]]

示例 3:

输入: strs = ["a"]

输出: [["a"]]

思路(排序,遍历)

另起一个数组sorted里面存放的字符串为strs中每一个字符串经过排序过后的结果。

original = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”] 经过排序后

sorted = [“aet”, “aet”, “ant”, “aet”, “ant”, “abt”]

构造结构体 dict 用于存放每一组 "eat" : "aet" ...... "bat" : "abt" 达到类似 key - value 的效果

创建数组Pairs用于存放每一对 key - value,数组Pairs[{"eat" : "aet"} ...... {"bat" : "abt"}]

此时在对数组Pairs进行排序,根据sorted字符串进行升序排序

遍历数组Pairs访问每一个排序后的字符串及Pairs[i].sorted

  • 当遇到第一个元素 或者 当前排序后的字符串Pairs[i].sorted 与 前一个字符串不相等时 Pairs[i - 1].sorted不相等时,新建一个数组,将原字符串Pairs[i].original 存放进入新建数组中,并且更新ret数组长度,新建数组长度设为1。
  • 当前排序后的字符串Pairs[i].sorted 与 前一个字符串不相等时 Pairs[i - 1].sorted相等时,Pairs[i].sorted对应的Pairs[i].original 存放进入前一步已创造的数组当中,并且更新对应数组的长度。

最后对结果ret进行返回即可。

详细

Pairs数组建立好后,Pairs.orinal 指向的是strs , Pairs.sorted 则是对应的字符串内容排序后

在这里插入图片描述

遍历开始时, i = 0 时需要创建一个子数组用于存放字符串Pairs[i].orinal

在这里插入图片描述

i = 1时 “tea” != “aet” 创建新的子数组用于存放字符串

在这里插入图片描述

当 i = 2时,Pairs[i].sorted 和 Pairs[i - i].sorted 相等,是字母异位词,将字符串存放于ret[i]数组中

在这里插入图片描述

后续情况和上述两种相似,当遍历完Pairs时,得到结果ret返回

代码实现

struct dict{
    char* original;
    char* sorted;
};

int cmpChar(const void* a,const void* b){
    return *(const char*)a - *(const char*)b;
}

int cmpPairs(const void* a,const void* b){
    struct dict* tmp_a = (struct dict*)a;
    struct dict* tmp_b = (struct dict*)b;
    return strcmp(tmp_a->sorted,tmp_b->sorted);
}

char*** groupAnagrams(char** strs, int strsSize, int* returnSize, int** returnColumnSizes){
    //判断给定数组是否为空
    if(NULL == strs || 0 == strsSize){
        return NULL;
    }

    //初始化Pairs数组,并为其分配内存空间
    //Pairs数组每个元素是struct dict类型,数组长度和strs数组长度相同
    struct dict* Pairs = malloc(sizeof(struct dict) * strsSize);

    //遍历并拷贝strs中的每个字符串,并对每个字符串内部进行排序
    for(int i = 0; i < strsSize; i++){

        //为字符串分配空间,用于保存strs数组中每个字符串
        char* sorted = malloc(sizeof(char) * (strlen(strs[i]) + 1));

        //将strs[i] 拷贝到 sorted  ( strs[i] ==> "bat" , sorted == "bat") 
        strcpy(sorted,strs[i]);

        //排序函数,对strs中每个字符串内部进行排序  数组首地址,数组长度,数组元素所占空间大小,比较函数
        qsort(sorted,strlen(strs[i]),sizeof(char),cmpChar);

        //将字符串首地址赋值
        Pairs[i].original = strs[i];
        Pairs[i].sorted = sorted;
    }

    //对Pairs数组进行排序
    qsort(Pairs,strsSize,sizeof(struct dict),cmpPairs);

    //为返回结果ret分配内存空间
    char*** ret = malloc(sizeof(char **) * strsSize);

    //为保存子数组长度的数组分配内存空间
    *returnColumnSizes = malloc(sizeof(int) * strsSize);

    //对返回的ret数组长度初始化
    *returnSize = 0;    

    //遍历Pairs
    for(int i = 0; i < strsSize; i++){
        //当为第一个字符串 或者 当前字符串和上一个字符串不相等时,需要开辟新数组
        if(0 == i || strcmp(Pairs[i].sorted,Pairs[i - 1].sorted) != 0 ){
            //记录当前添加元素应该添加到的下标位置
            int lastIndex = (*returnSize);            

            //为数组分配内存空间
            ret[lastIndex] = malloc(sizeof(char *));    

            //将字符串首地址赋值给新开辟数组的第一个元素            
            ret[lastIndex][0] = Pairs[i].original;

            //ret数组长度增加
            (*returnSize)++;

            //记录新开辟数组的长度
            (*returnColumnSizes)[lastIndex] = 1;
        }else{    //当前字符串和上一个字符串相等时,无需开辟新数组,将当前字符串添加到 ret 最后一个子数组后
            //ret 最后一个子数组的下标  (*returnSize)表示长度,下标为长度 - 1
            int lastIndex = (*returnSize) - 1;

             //获取该字符串要添加到子数组的下标 (是当前子数组未添加元素的长度)
            int lastSubIndex = (*returnColumnSizes)[lastIndex];

            //对 ret 最后一个子数组扩容
            ret[lastIndex] = realloc(ret[lastIndex],sizeof(char *) *(lastSubIndex + 1));

            //将字符串首地址赋值
            ret[lastIndex][lastSubIndex] = Pairs[i].original;

            //最后一个子数组长度  + 1
            (*returnColumnSizes)[lastIndex] = lastSubIndex + 1;
        }
    }

    return ret;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值