leetcode (30) Substring with Concatenation of All Words

原创 2016年06月01日 15:58:46

原题链接:https://leetcode.com/problems/substring-with-concatenation-of-all-words/


题目:30. 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 wordsexactly 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).


题目意思:就是在s中找到所有的序号,从这些序号开始的所有的单词,全都包含了words中的单词,并且中间不能含有其它的单词。


解题思路:

(1)首先应该建一个hashmap,以words的单词作为map的key,以words中出现的数量作为value值。

(2)在s中进行遍历,因为每个words中的单词长度都是固定的length,所以依次比较(i,i+length-1),(i+length,i+2*length-1),(i+2*length, i+3*length-1)。。。看是否能和words中的单词都能进行匹配。

(3)若可以匹配,则保存i,继续判断s中的i+1作为起始位置。。。依次类推


代码实现:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 1000

typedef struct Node{
    char *word;
    int times;
    struct Node *next;
}data;

int hash(char *word){
    int i = 0, h = 0;
    for(i=0; word[i]; i++) {
        h = (h*31+word[i])%SIZE;
    }
    return h;
}
//根据words构建字典
int insertMap(data **map, char *word, int length) {
    int h = hash(word);
    if (map[h] == NULL) {
        map[h] = (data *) malloc (sizeof(data));
        map[h]->word = (char *) malloc (sizeof(char) * (length+1));
        strcpy(map[h]->word, word);
        map[h]->times = 1;
        map[h]->next = NULL;
        return 1;
    } else {
        data *p = map[h];
        while (p->next != NULL) {
            if (strcmp(p->word, word) == 0) {
                p->times++;
                return p->times;
            }
            p = p->next;
        }
        if (strcmp(p->word, word) == 0) {
            p->times++;
            return p->times;
        } else {
            data *tmp = (data *) malloc (sizeof(data));
            tmp->word = (char *) malloc (sizeof(char) * (length+1));
            strcpy(tmp->word, word);
            tmp->times = 1;
            p->next = tmp;
            tmp->next = NULL;
            return 1;
        }
    }
}
//查询字典,并返回此单词的数目
int findMap(data **map, char *sub) {
    int h = hash(sub);
    if (map[h] == NULL) {
        return -1;
    } else {
        data *p = map[h];
        while (p != NULL) {
            if (strcmp(p->word, sub) == 0) {
                return p->times;
            }
            p = p->next;
        }
        return -1;
    }
}

char *substring(char *s, int start, int len) {
    char *sub = (char *) malloc (sizeof(char) * (len+1));
    int i=0;
    for (; i < len; i++) {
        sub[i] = s[i+start];
    }
    sub[i] = '\0';
    return sub;
}
/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findSubstring(char* s, char** words, int wordsSize, int* returnSize) {
    *returnSize = 0;
    if (s == NULL || words == NULL) {
        return NULL;
    }
    int sLen = strlen(s), wLen = strlen(words[0]);
    int *result = (int *) malloc (sizeof(int) * (sLen-wLen*wordsSize+1));
    data **map = (data **) malloc (sizeof(data *) * SIZE);
    data **tmp = (data **) malloc (sizeof(data *) * SIZE);
    int i, j;
    for (i = 0; i < SIZE; i++) {
        map[i] = NULL;
        tmp[i] = NULL;
    }

    //构建字典
    for (i = 0; i < wordsSize; i++) {
        insertMap(map, words[i], wLen);
    }

    for (i = 0; i <= sLen-wLen*wordsSize; i++) {
        for (j = 0; j < SIZE; j++) {
            if (tmp[j] != NULL) {
                free(tmp[j]);
                tmp[j] = NULL;
            }
        }
        for (j = 0; j < wordsSize; j++) {
            char *sub = substring(s, i+j*wLen, wLen);
            int mapnum = findMap(map, sub);
            if (mapnum == -1) break;
            int num = insertMap(tmp, sub, wLen);
            if (num > mapnum) break;
            free(sub);
        }
        if (j >= wordsSize) {
            result[(*returnSize)++] = i;
        }
    }
    for (i = 0; i < SIZE; i++) {
        if (map[i] != NULL) {
            free(map[i]);
        }
    }
    free(map);
    return result;
}


以上代码参考了别人的一篇博客。


还有一种方法是滑动窗口的方法,思路仍然是维护一个窗口,如果当前单词在字典中,则继续移动窗口右端,否则窗口左端可以跳到字符串下一个单词了:http://blog.csdn.net/linhuanmars/article/details/20342851


相关文章推荐

[LeetCode] 30. Substring with Concatenation of All Words

leetcode string

Leetcode||30.Substring with Concatenation of All Words

30. Substring with Concatenation of All Words Total Accepted: 68319Total Submi...

LeetCode 30 Substring with Concatenation of All Words (C,C++,Java,Python)

Problem: You are given a string, s, and a list of words, words, that are all of the same length...

LeetCode 30 - Substring with Concatenation of All Words

一、问题描述 Description:Description: You are given a string, ss, and a list of words, wordswords, ...

LeetCode 30 Substring with Concatenation of All Words(AC自动机+滑动窗口)

题意:给出一个字符串,和一个字典,字典中有若干个单词(可能有重复单词),每个单词的长度相等,现在要求所有字典中全部单词的任意组合在字符串中的起始下标。 思路:首先先说一下用ac自动机复杂度可以优化到O...

【一天一道LeetCode】#30. Substring with Concatenation of All Words

注:这道题之前跳过了,现在补回来一天一道LeetCode系列(一)题目 You are given a string, s, and a list of words, words, that ar...

[LeetCode]30.Substring with Concatenation of All Words

【题目】 You are given a string, S, and a list of words, L, that are all of the same length. Find all ...

LeetCode 30: Substring with Concatenation of All Words

Substring with Concatenation of All WordsYou are given a string, s, and a list of words, words, that...

leetcode30---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 al...
  • will130
  • will130
  • 2015年12月22日 15:29
  • 180

LeetCode_30---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 sta...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:leetcode (30) Substring with Concatenation of All Words
举报原因:
原因补充:

(最多只允许输入30个字)