【C语言】Leetcode 916. 单词子集

这篇博客探讨了解决LeetCode 916问题的思路,即判断一个单词数组A中是否存在单词是另一个数组B中所有单词的子集。首先介绍了暴力解法,通过比较字符数量来判断,然后优化算法,利用动态规划存储B中每个字符串的最大长度,再与A中字符串进行比较。如果A中每个字符串的长度都大于等于B中对应的最大长度,那么该单词是通用的。文章链接提供了更多细节。
摘要由CSDN通过智能技术生成

解题思路:
1、开始阶段使用暴力解法,通过将A/B字符中中的’a’~‘z’ 26个字符的数量统计出来,然后计算A中的每个字符串是否大于B中的每个字符串的长度。
2、优化算法:BNum[BSize][MAX_COL] 计算每一列的最大的长度,然后把A中的每个字符串与最大长度比较,是否满足ANum[ASize][MAX_COL] > maxOfCol[MAX_COL],如果全部满足,可以认为是满足条件的。只要有一个不满足,则不满足这个条件。

https://leetcode-cn.com/problems/word-subsets/
我们给出两个单词数组 A 和 B。每个单词都是一串小写字母。
现在,如果 b 中的每个字母都出现在 a 中,包括重复出现的字母,那么称单词 b 是单词 a 的子集。 例如,“wrr” 是 “warrior” 的子集,但不是 “world” 的子集。
如果对 B 中的每一个单词 b,b 都是 a 的子集,那么我们称 A 中的单词 a 是通用的。
你可以按任意顺序以列表形式返回 A 中所有的通用单词。

#define MAX_LEN 11
#define MAX_COL 26
#define MAX(a,b) (a) > (b) ? (a) : (b)

char ** wordSubsets(char ** A, int ASize, char ** B, int BSize, int* returnSize){
    int **BNum = (int **) malloc (BSize * sizeof(int *));
    for (int i = 0; i < BSize; i++){
        BNum[i] = (int *) malloc (26 * sizeof(int));
        memset(BNum[i], 0, 26 * sizeof(int));
        int len = strlen(B[i]);
        for (int j = 0; j < len; j++){
            BNum[i][B[i][j] - 'a']++;
        }
    }

    int maxOfCol[MAX_COL] = {0};
    for (int j = 0; j < MAX_COL; j++){
        int maxj = 0;
        for (int i = 0; i < BSize; i++){
            maxj = MAX (maxj, BNum[i][j]);
            maxOfCol[j] = maxj;
        }
    }

    char **res = (char **) malloc(ASize * sizeof(char*));
    *returnSize = 0; 
    int **ANum = (int **) malloc (ASize * sizeof(int *));
    for (int i = 0; i < ASize; i++){
        ANum[i] = (int *) malloc (26 * sizeof(int));
        memset(ANum[i], 0, 26 * sizeof(int));
        int len = strlen(A[i]);
        for (int j = 0; j < len; j++){
            ANum[i][A[i][j] - 'a']++;
        }
        int flag = 1; 
        for (int j = 0; j < MAX_COL; j++){
            if(ANum[i][j] < maxOfCol[j]){
                flag = 0;
                break;
            }
        }
        if(flag == 1){
            res[*returnSize] =  (char *) malloc (MAX_LEN * sizeof(char));
            memset(res[*returnSize], 0, MAX_LEN);
            strcpy (res[*returnSize], A[i]);
            (*returnSize)++;
        }
    }
    return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值