題目描述
給定一個字符串 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;
}