leetcode 30. Substring with Concatenation of All Words

第一次写,就挨个字母判断,判断从该字母开始的每个单词是不是出现过,出现过就失败。但是提交后发现单词表可以有重复。修改成遇到出现过的单词也继续扫描单词表,但是超时了。发现需要对单词表做一个预处理,得到每一个单词在从当前位置以后出现的次数,当然相同的单词只有第一个的次数是有效的。然后对于某一个字母扫描单词表。扫描到一个单词就把单词的次数减1,正好全都减成0就匹配成功。

int* findSubstring(char* s, char** words, int wordsSize, int* returnSize) {
    int lenWord,lenS;
    int flag2,flag3;
    int *ans;
    ans=(int *)malloc(sizeof(int)*1000);
    if(wordsSize>=1)
        lenWord=strlen(words[0]);
    else
        return NULL;
    int i,j,m,n,l;
    lenS=strlen(s);


    int *flags,*flagsCount;
    flags=(int *)malloc(sizeof(int)*wordsSize);
    flagsCount=(int *)malloc(sizeof(int)*wordsSize);
/*    for(i=0;i<wordsSize;i++)
        flags[i]=0;*/
    for(i=0;i<wordsSize;i++)
        flags[i]=1;  //当前单词算一个
    //int *numWord;  //记录每个不重复单词在单词表中出现的词数
    //记录每个单词从当前位置到末尾出现的次数,那么这个单词第一次出现的地方对应的次数就是这个单词总共出现的次数
    for(i=0;i<wordsSize;i++)
    {
        for(j=i+1;j<wordsSize;j++)
            if(strcmp(words[i],words[j])==0)
                flags[i]++;
        flagsCount[i]=flags[i];
    }



    for(i=0;i<=(lenS-lenWord*wordsSize);i++)
    {
        for(l=0;l<wordsSize;l++)
            flagsCount[l]=flags[l];
        flag2=0;
        for(j=0;j<wordsSize;j++)//向后检查wordsSize个单词
        {
            //flag1=0;  //第j个单词匹配失败
            flag3=0;  //当前单词找不到匹配的单词
            for(m=0;m<wordsSize;m++) //检查是否和单词组中的某个单词匹配
            {
                for(n=0;n<lenWord;n++)
                {
                    if(s[i+j*lenWord+n]==words[m][n])
                        ;
                    else
                        break;
                }

                if(n==lenWord&&flagsCount[m]>0)   //当前单词匹配成功而且这个单词还没有减完
                {
                    flag3=1;
                    flagsCount[m]=flagsCount[m]-1;
                    break;   //匹配成功了就不用再检查了
                }
                else if(n==lenWord&&flagsCount[m]==0)   //该单词不够了
                {
                    flag2=1;
                    break;
                }
            }
            if(m==wordsSize&&flag3==0)  //当前单词找不到一个匹配的单词
            {
                break;
            }
            if(flag2==1)   //虽然匹配到该单词,但是该单词的个数不够了
            {
                break;
            }

        }
        if(j==wordsSize)  //全部匹配
        {
            ans[(*returnSize)++]=i;
        }
    }
    return ans;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值