LeetCode 30 Substring with Concatenation of All Words(与所有文字串联子串)(*)

原创 2015年11月18日 21:30:43

翻译

给定一个字符串S,一个单词的列表words,全是相同的长度。

找到的子串(多个)以s即每个词的字串联恰好一次并没有任何插入的字符所有的起始索引。

原文

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).

代码

难度对我来说还是太大了,但还是先发个博客占个位置,不然以后顺序就不连串了……

// for sort the |words|
int strcmp1(const void* p1, const void* p2) {
    return strcmp(*(char**)p1, *(char**)p2);
}

// to handle duplicate words in |words|
struct word_t {
    char* w;
    int count;
    int* pos;
    int cur;
};

int word_t_cmp(const void* p1, const void* p2) {
    return strcmp(((const struct word_t*)p1)->w, ((const struct word_t*)p2)->w);
}

/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 * 
 * It is a variant of the longest-substring-without-repetition problem
 */
int* findSubstring(char* s, char** words, int wordsSize, int* returnSize) {
    if (!s || wordsSize == 0 || strlen(s) < wordsSize*strlen(words[0])) {
        *returnSize = 0;
        return NULL;
    }
    if (strlen(s) == 0 && strlen(words[0]) == 0) {
        *returnSize = 1;
        int* ret = (int*) malloc(sizeof(int));
        ret[0] = 0;
        return ret;
    }

    int n = strlen(s);
    int k = strlen(words[0]);
    // sort |words| first, prepare for binary search
    qsort(words, wordsSize, sizeof(char*), strcmp1);
    // construct array of word_t
    // @note please note that after construction, |wts| is already sorted
    struct word_t* wts = (struct word_t*) malloc(wordsSize * sizeof(struct word_t));
    int wtsSize = 0;
    for (int i = 0; i < wordsSize;) {
        char* w = words[i];
        int count = 1;
        while (++i < wordsSize && !strcmp(w, words[i]))
            count++;
        struct word_t* wt_ptr = wts + wtsSize++;
        wt_ptr->w = w;
        wt_ptr->count = count;
        wt_ptr->pos = (int*) malloc(count * sizeof(int));
        wt_ptr->cur = 0;
    }
    // store one word
    struct word_t wt;
    wt.w = (char*) malloc((k+1) * sizeof(char));
    // return value
    int cap = 10;
    int* ret = (int*) malloc(cap * sizeof(int));
    int size = 0;
    for (int offset = 0; offset < k; offset++) {
        // init word_t array
        for (int i = 0; i < wtsSize; i++) {
            struct word_t* wt_ptr = wts + i;
            for (int j = 0; j < wt_ptr->count; j++)
                wt_ptr->pos[j] = -1;
            wt_ptr->cur = 0;
        }
        int start = offset; // start pos of current substring
        int len = 0; // number of words encountered

        for (int i = offset; i <= n - k; i += k) {
            strncpy(wt.w, s+i, k);
            wt.w[k] = '\0';
            struct word_t* p = (struct word_t*) bsearch(&wt, wts, wtsSize, sizeof(struct word_t), word_t_cmp);
            if (!p) {
                start = i + k;
                len = 0;
                continue;
            }
            // @note the following five lines covers extra occurrence of
            // (possible duplicate) word, you can draw some special case
            // on a paper if it's hard to understand why it could cover
            // all boundary conditions
            // |p->cur| and |p->pos| implement a simple rounded queue,
            // and |p->cur| always point to the smallest index position
            int pos = p->pos[p->cur];
            p->pos[p->cur++] = i;
            if (p->cur >= p->count)
                p->cur -= p->count;
            if (pos < start) { // valid occurrence of this word in current substring started at |start|
                len++;
                if (len == wordsSize) { // all words encounterd, add to result set
                    if (size == cap) { // extend the array
                        cap = 2*cap;
                        int* tmp = (int*) malloc(cap * sizeof(int));
                        memcpy(tmp, ret, size*sizeof(int));
                        free(ret);
                        ret = tmp;
                    }
                    ret[size++] = start;
                    // move substring forward by one word length
                    start += k;
                    len--;
                }
            } else { // extra occurence of (possible duplicat) word encountered, update |start| and |len|
                start = pos + k;
                len = (i - start)/k + 1;
            }
        }
    }

    // cleanup
    for (int i = 0; i < wtsSize; i++)
        free(wts[i].pos);
    free(wts);

    *returnSize = size;
    if (size == 0) {
        free(ret);
        ret = NULL;
    }
    return ret;
}
版权声明:本文为 nomasp柯于旺 原创,未经许可严禁转载!欢迎访问我的博客:http://blog.csdn.net/nomasp

相关文章推荐

洛谷 P3811 【模板】乘法逆元

洛谷 P3811 【模板】乘法逆元题目题目背景这是一道模板题题目描述给定n,p求1~n中所有整数在模p意义下的乘法逆元。输入输出格式输入格式: 一行n,p输出格式: n行,第i行表示i在模p意义下...

洛谷 P2193 HXY和序列

洛谷 P2193 HXY和序列题目题目描述HXY突发奇想,她想要找到一个正整数序列,满足序列中所有的数不超过n,序列长度为p,且除了第一个数外,所有的数都能被前一个数整除(即是前一个数的倍数)。很快她...

【记录】绵东实三校联考 验题记录

感觉已经快成御用验题小天使 = =。。 姜神出的题,然后cyx小朋友成功AK了   【T1】 排队 Waiting 这题和之前有一道NOIp题差不多。。做法也是一样的。。排个序就万事大吉了。 听说有人...

【See you】

遇见你 花光此生所有运气。 握紧彼此的手 我们却还是走散。 谢谢你带给我的这个世界。 记得小学英语老师说 See you 其实 一般是再也不见的意思。 那么 See you.

【OI再见】

Forever. End.

洛谷 P1799 数列_NOI导刊2010提高(06)

洛谷 P1799 数列_NOI导刊2010提高(06)题目题目描述虽然msh长大了,但她还是很喜欢找点游戏自娱自乐。有一天,她在纸上写了一串数字:1,l,2,5,4。接着她擦掉了一个l,结果发现剩下...

洛谷 P2058 海港

洛谷 P2058 海港题目题目描述小K是一个海港的海关工作人员,每天都有许多船只到达海港,船上通常有很多来自不同国家的乘客。小K对这些到达海港的船只非常感兴趣,他按照时间记录下了到达海港的每一艘船只情...

洛谷 P2759 奇怪的函数

洛谷 P2759 奇怪的函数题目题目描述使得 x^x 达到或超过 n 位数字的最小正整数 x 是多少?输入输出格式输入格式: 一个正整数 n输出格式: 使得 x^x 达到 n 位数字的最小正整数 ...

洛谷 P2423 双塔

洛谷 P2423 双塔题目题目描述2001年9月11日,一场突发的灾难将纽约世界贸易中心大厦夷为平地,Mr. F曾亲眼目睹了这次灾难。为了纪念“911”事件,Mr. F决定自己用水晶来搭建一座双塔。M...

洛谷 P1895 数字序列

洛谷 P1895 数字序列题目题目背景查找数字题目描述在下列的无穷数字序列1121231234123451234561234567123456781234567891234567 8910123456...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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