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;
}


 

posted @ 2015-07-16 18:28  gqtc  阅读(120)  评论(0编辑  收藏  举报