leetcode (30) Substring with Concatenation of All Words

来源:互联网 发布:淘宝卖家修改配送地址 编辑:程序博客网 时间:2024/05/22 09:02

原题链接: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


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机看百度文章总是跳转怎么办 美度舵手滑丝怎么办 小区房产证办不下来怎么办 美海军陆战队进驻台湾大陆怎么办? 束脚裤带子怎么办系 眼角弄伤了应该怎么办 浴盆下水盖坏了怎么办 冒险岛勋章多了怎么办 玉手镯取不下来怎么办?终极绝招! 陆金所收益低怎么办 陆金所登录密码忘记怎么办 陆金所理财逾期怎么办 死亡家属晚上来闹怎么办 开车撞到人家属闹要请护工怎么办 骑马与砍杀战团打下城市怎么办 我的脑子有问题怎么办 公司外派异地工作医保怎么办 老鼠死在墙里面怎么办 父亲再婚婚后对我不好怎么办 皮衣搽了护理油后不亮了怎么办 新买的衣服皱了怎么办 新买的裙子很皱怎么办 新买的风衣很皱怎么办 新买的裙子皱了怎么办 货拉拉准点率低怎么办 定机票名字打错了怎么办 做坏事被发现了怎么办 在阳台做被发现怎么办 有秘密被发现了怎么办 微店没有收到货怎么办 cf与主机连接不稳定怎么办 穿越火线与主机连接不稳定怎么办 word被锁定无法编辑怎么办 平衡车系统乱了怎么办 监控老是滴滴的响怎么办 磁盘已满 文件未保存怎么办 cocos只有代码没有项目怎么办 电脑系统管理员密码忘记了怎么办 魔兽小队不显示职业颜色怎么办 魔兽多余的橙装怎么办? f117-f6不读硬盘怎么办