题目描述
给定一个字符串 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;
}