Substring with Concatenation of All Words
You are given a string, s, and a list of words, “words”, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.
For example, given:
s: "barfoothefoobarman"
words: ["foo","bar"]
You should return the indices: [0,9]. (order does not matter).
思路:本题本质上与《Longest SubstringWithout Repeating Characters》是一样的。但是要注意几个地方:
”words”中的单词可能会重复;
left指针只能一步一步的走,不能跨越,比如这样的字符串s和words:
s: abcdefghidef
words: [“abc”, ”bcd”, ”cde”, ”def”, “ghi”]
本题还是需要使用hash表来快速判断是否找到了words中的单词,注意hash表中还需要记录该单词出现的次数。
如果没找到,则left++,如果找到了,但是找到的单词的次数已经超过了words中的次数,同样的left++。代码如下:
typedef struct hashnode
{
char *str;
int nums;
struct hashnode *next;
}HashNode;
#define NHASH 31
#define MULT 31
unsigned int hash(char *p)
{
unsigned int h = 0;
for (; *p; p++)
h = MULT *h + *p;
return h % NHASH;
}
int isfindword(char *word, HashNode **wordhash, int hashlen)
{
int hashvalue = hash(word);
HashNode *ptr = wordhash[hashvalue];
while(ptr != NULL)
{
if(ptr->str == NULL) return 0;
if(strcmp(ptr->str, word) == 0)
{
return ptr->nums;
}
ptr = ptr->next;
}
return 0;
}
void freehash(HashNode **wordhash, int hashsize)
{
int i = 0;
HashNode *ptr = NULL;
HashNode *qtr = ptr;
while(i < hashsize)
{
ptr = wordhash[i];
while(ptr != NULL)
{
qtr = ptr;
ptr = ptr->next;
free(qtr->str);
free(qtr);
}
wordhash[i] = NULL;
i++;
}
return;
}
int inserttohash(HashNode **map, char *word, int wordlen)
{
int hashvalue = hash(word);
HashNode *hp = map[hashvalue];
HashNode *hq = hp;
while(hp != NULL)
{
if(strcmp(hp->str, word) == 0)
{
hp->nums += 1;
break;
}
else
{
hq = hp;
hp = hp->next;
}
}
if(hp == NULL)
{
hp = calloc(1, sizeof(HashNode));
hp->str = calloc(wordlen+1, sizeof(char));
memcpy(hp->str, word, wordlen);
hp->nums= 1;
if(map[hashvalue] == NULL) map[hashvalue] = hp;
else hq->next = hp;
}
return hp->nums;
}
int* findSubstring(char* s, char** words, int wordsSize, int* returnSize)
{
int hashlen = NHASH;
HashNode **constwordhash = calloc(hashlen, sizeof(HashNode *));
HashNode **acthash = calloc(hashlen, sizeof(HashNode *));
int i;
int hashvalue;
int wordlen = strlen(words[0]);
for(i = 0; i < wordsSize; i++)
{
inserttohash(constwordhash, words[i], wordlen);
}
int findnums = 0;
int getindexres = -1;
int *res = calloc(strlen(s), sizeof(int));
int resindex = 0;
int left = 0;
i = left;
int forcounts = 0;
int tstrlen = strlen(s);
while(i < tstrlen && left <= tstrlen-wordsSize*wordlen)
{
forcounts++;
char *word = calloc(wordlen+1, sizeof(char));
memcpy(word, s+i, wordlen);
getindexres = isfindword(word, constwordhash, hashlen);
if(getindexres == 0 || getindexres < inserttohash(acthash, word, wordlen))
{
findnums = 0;
left++;
i = left;
freehash(acthash, hashlen);
free(word);
continue;
}
else
{
free(word);
findnums++;
if(findnums == wordsSize)
{
res[resindex++] = left;
findnums = 0;
left++;
i = left;
freehash(acthash, hashlen);
continue;
}
i += wordlen;
}
}
*returnSize = resindex;
freehash(constwordhash, hashlen);
freehash(acthash, hashlen);
free(constwordhash);
free(acthash);
return res;
}
呵呵

浙公网安备 33010602011771号