學渣帶你刷Leetcode0030串聯所有單詞的子串

題目描述

給定一個字符串 s 和一些長度相同的單詞 words。找出 s 中恰好可以由 words 中所有單詞串聯形成的子串的起始位置。

注意子串要與 words 中的單詞完全匹配,中間不能有其他字符,但不需要考慮 words 中單詞串聯的順序。

 

示例 1:

輸入:
  s = "barfoothefoobarman",
  words = ["foo","bar"]
輸出:[0,9]
解釋:
從索引 0 和 9 開始的子串分別是 "barfoo" 和 "foobar" 。
輸出的順序不重要, [9,0] 也是有效答案。
示例 2:

輸入:
  s = "wordgoodgoodgoodbestword",
  words = ["word","good","best","word"]
輸出:[]

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

白話題目:

真難啊,用words中的字符串拼成s中的某一段就好。

算法:

  (1)輸入的處理,二維數組存儲word

(2)真難啊,C語言啥都得自己實現

1.構造hash表,包含字符串內容和出現的頻次;
2.由於可能從第0~wordlen之前作爲開始位,需要做開始點的遍歷;
3.使用雙指針L,R,每次遍歷一個單詞長度,如果hash表中有單詞的計數大於0 ,R指針繼續往前跳;失敗了就把L跟進;

要是有些詞多次出現也屬於不行,L也得跟進。

4.核心是R走,消耗hash表,L走遇到hash表裏面的值歸還。

先看例子

詳細解釋關注 B站  【C語言全代碼】學渣帶你刷Leetcode 不走丟 https://www.bilibili.com/video/BV1C7411y7gB

C語言完全代碼

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
// #define MAX_WORDS 10000
struct words
{
    char *word;
    int cnt;
};

int numCount(struct words *hash, int hashNum)  //判斷hash表要是都是0就合格了。
{
    int i;
    int allzeros = 0;
    for (i = 0; i < hashNum; i++)
    {
        if (hash[i].cnt > 0)
            allzeros =1;
        if (hash[i].cnt < 0)
            return  -1;
    }
    //printf("numcount is %d\n",allzeros);
    return allzeros;
}

int findInHash(struct words *hash,int hashNum,char *c,int word_len,char Type)  //在沒有匹配的時候遇到單詞就減少,遇到合格的時候,逐個退出,值加一
{
    int i;
    int findflag = 0;
    for (i = 0; i < hashNum; i++)
    {
        if (strncmp(hash[i].word, c, word_len) == 0)
        {
            if (Type == 'R')
                hash[i].cnt--;
            else
                hash[i].cnt++;
            findflag=1;
            break;
        }
    }
    return findflag;
}

char * substr(char *s,int start,int length)
{
    char  *slice_s = (char *)malloc(sizeof(char) * (length+1));  //不malloc出去就廢了  char slice_s[]
    strncpy(slice_s,s+start,length);
    slice_s[length]='\0';
    //puts(slice_s);
    return slice_s;
}


int* findSubstring(char * s, char ** words, int wordsSize, int* returnSize)
{
    //如果輸入的數量不行就gameover
    if (s == NULL || wordsSize == 0  || *words == NULL)
    {
        *returnSize = 0;
        return NULL;
    }

    int s_len=strlen(s);
    int Unilength = strlen(words[0]);

    //char *substring=substr(s,0,Unilength);
    // printf("%s ", dest);//

    //C語言得自己寫這種hash表 ,內容+數量
    struct words *hash = (struct words*)malloc(sizeof(struct words) * wordsSize);
    int i,j;
    int hashNum=0;

    for (i = 0; i < wordsSize; i++)   //假設3個單詞
    {
        for (j = 0; j < hashNum; j++)
        {
            if (hash[j].word && (strcmp(words[i], hash[j].word) == 0))
            {
                hash[j].cnt++;
               printf("word=%s ,hashnum =%d ,cnt =%d\n",hash[j].word,hashNum,hash[j].cnt);
                break;
            }
        }
        if (j == hashNum)   //0的情況在這裏
        {
            char *tmp = (char *)malloc(sizeof(char) * Unilength+1);
            strcpy(tmp, words[i]);
            hash[hashNum].word = tmp;
            hash[hashNum].cnt = 1;
            hashNum++;
            printf("word =%s, hashnum =%d,cnt=%d\n",hash[hashNum - 1].word,hashNum,hash[hashNum-1].cnt);  //注意是hasnum-1;
        }
    }

    int count = 0;
    int *ret = (int *)malloc(sizeof(int) * s_len);
    for(i=0; i<Unilength; i++)
    {
        int L=i;
        int R=i;
      //  printf("L= %d,R=%d\n",L,R);
        while(L<=s_len&&R<=s_len)
        {
            //printf("hash數量%d\n",numCount(hash, hashNum));
            int test=numCount(hash,hashNum);
            if(R <= s_len&&numCount(hash, hashNum) > 0 )  //
            {
                if(findInHash(hash,hashNum,&s[R],Unilength,'R'))
                {
                    R=R+Unilength;
                }
                else  //除了吐出來,L要一直到右側
                {
                    R=R+Unilength;
                    while (L <=s_len && L< R)
                    {
                        findInHash(hash,hashNum,&s[L],Unilength,'L');
                        L += Unilength;
                    }
                }
            }
            else if(R<=s_len&&numCount(hash, hashNum) == 0)
            {
                //printf("結果= %d\n",L);
                ret[count++] = L;
                findInHash(hash,hashNum,&s[L],Unilength,'L');
                L += Unilength;
            }
             else {
                    findInHash(hash,hashNum,&s[L],Unilength,'L');
                         L += Unilength;

            }


        }

    }
    *returnSize=count;
    return ret;
}

int main()
{
    printf("可以輸入的s串: xfoofoobarfoobarxx\n");
    char  *s;
    s=(char *)malloc(sizeof(char));
    //scanf("%s",s);  //處理不了空格
    gets(s);

    printf("輸入foo bar foo的總個數 3\n");
    int wordsSize;
    scanf("%d",&wordsSize);
    //char* strs[strsSize];  都行
    char **words=(char **)malloc(wordsSize*sizeof(char));
    int m;

    for ( m = 0; m < wordsSize; m ++)      //單詞總個數
    {
        words[m]=(char*)malloc(100*sizeof(char));
        scanf("%s",words[m]);   //就是指針的地址
    }
    printf("\n");
    for ( m = 0; m < wordsSize; m ++)
    {
        printf("%s\n",words[m]);
    }

    int returnSize=0;
    int *result=findSubstring( s, words, wordsSize, &returnSize);

    int i;
    for(i=0; i<returnSize; i++)
    {
        printf("------------%d ", result[i]);//
    }

    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章