关闭

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

标签: substringleetcodewordsstrcmpconst
2174人阅读 评论(0) 收藏 举报
分类:

翻译

给定一个字符串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;
}
3
0
查看评论

[leetcode] 30. Substring with Concatenation of All Words 解题报告

题目链接:https://leetcode.com/problems/substring-with-concatenation-of-all-words/ You are given a string, s, and a list of words, words, that ...
  • qq508618087
  • qq508618087
  • 2015-12-18 04:40
  • 581

[Leetcode]30. Substring with Concatenation of All Words @python

题目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 con...
  • qian2729
  • qian2729
  • 2016-01-16 22:19
  • 414

LeetCode | 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 starting indices of substring(s) in S that is a...
  • a45872055555
  • a45872055555
  • 2014-08-17 20:54
  • 468

[LeetCode] 030. Substring with Concatenation of All Words (Hard) (C++/Java)

[LeetCode] 030. Substring with Concatenation of All Words (Hard) (C++/Java)
  • hcbbt
  • hcbbt
  • 2015-03-06 22:14
  • 2990

【LeetCode】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 starting indices of substring(s) in S th...
  • ljiabin
  • ljiabin
  • 2014-12-29 15:45
  • 7453

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. Find all starting indices of substring...
  • runningtortoises
  • runningtortoises
  • 2015-05-14 13:13
  • 1126

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 starting indices of substring(s) in s that is a con...
  • fly_yr
  • fly_yr
  • 2015-08-24 20:51
  • 2291

(Java)LeetCode-30. Substring with Concatenation of All Words

这道题Hard模式,比较复杂,又没有用到很经典的算法,卡在这道题很长时间了。 首先比较直观的解法package datastru; import java.util.ArrayList; import java.util.HashMap; import java.util.List; impo...
  • u012848330
  • u012848330
  • 2016-07-31 22:03
  • 300

Substring with Concatenation of All Words -- LeetCode

原题链接: http://oj.leetcode.com/problems/substring-with-concatenation-of-all-words/  这道题看似比较复杂,其实思路和Longest Substring Without Repeating Charac...
  • linhuanmars
  • linhuanmars
  • 2014-03-03 04:00
  • 25538

leetcode 30 Substring with Concatenation of All Words (java)

题目: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 co...
  • wl0627
  • wl0627
  • 2016-09-09 10:57
  • 77
    个人资料
    • 访问:1610592次
    • 积分:24247
    • 等级:
    • 排名:第327名
    • 原创:521篇
    • 转载:0篇
    • 译文:29篇
    • 评论:798条
    Billboard:
    微博
    博客专栏
    最新评论