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

翻译

给定一个字符串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;
}
时间: 2024-08-03 11:29:12

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

[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 starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters. For example, given:

[LeetCode] Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest subst

&lt;font color=&quot;red&quot;&gt;[置顶]&lt;/font&gt;

Profile Introduction to Blog 您能看到这篇博客导读是我的荣幸,本博客会持续更新,感谢您的支持,欢迎您的关注与留言.博客有多个专栏,分别是关于 Windows App开发 . UWP(通用Windows平台)开发 . SICP习题解 和 Scheme语言学习 . 算法解析 与 LeetCode等题解 . Android应用开发 ,而最近会添加的文章将主要是算法和Android,不过其它内容也会继续完善. About the Author 独立 Windows App 和

leetcode难度及面试频率

转载自:LeetCode Question Difficulty Distribution               1 Two Sum 2 5 array sort         set Two Pointers 2 Add Two Numbers 3 4 linked list Two Pointers           Math 3 Longest Substring Without Repeating Characters 3 2 string Two Pointers      

LeetCode All in One 题目讲解汇总(持续更新中...)

终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 如果各位看官们,大神们发现了任何错误,或是代码无法通过OJ,或是有更好的解法,或是有任何疑问,意见和建议的话,请一定要在对应的帖子下面评论区留言告知博主啊,多谢多谢,祝大家刷得愉快,刷得精彩,刷出美好未来- 博主制作了一款iOS的应用"Leetcode Meet Me",里面有Leetcode上所有的题目,并且贴上了博主的解法,随时随地都能

LeetCode总结【转】

转自:http://blog.csdn.net/lanxu_yy/article/details/17848219 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近完成了www.leetcode.com的online judge中151道算法题目.除各个题目有特殊巧妙的解法以外,大部分题目都是经典的算法或者数据结构,因此做了如下小结,具体的解题思路可以搜索我的博客:LeetCode题解 题目 算法 数据结构 注意事项 Clone Graph BFS 哈希表 Word Ladder II

js字符串截取函数substr substring slice使用对比_javascript技巧

常用三个的字符串截取函数:substr substring slice,调用方式如下 复制代码 代码如下: stringObject.slice(start,end) stringObject.substr(start,length) stringObject.substring(start,end) 最明显的是substr,第二个参数是length,是截取长度,其他两个函数的第二个参数都是末尾字符的下标(这里并不包括该下标的字符,只截取到该字符的前一个字符) slice跟substring比,

js中substring和substr两者区别和使用方法_javascript技巧

在开始之前,先回顾下js中下标(数组元素/字符串中字符下标): 下标总是从0开始计数,例如 var arr = [1,2,3];//数组的长度为3,元素下标依次为:0,1,2 arr[0] = 1,arr[1]=2.. 字符串类似:如var s = "hello"://字符串长度为5,第一个字符'h'的下标为0,依次类推 String.substring( ):用于返回一个字符串的子串 用法如下:string.substring(from, to) 其中from指代要抽去的子串第一个字

mysql之字符串操作

写在前面 上篇文章学习了mysql常用的日期操作的函数,这篇文章将学习mysql的字符串操作的函数. 系列文章 mysql之创建数据库,创建数据表 mysql之select,insert,delete,update mysql之group by,order by mysql之count,max,min,sum,avg,celing,floor mysql之日期函数 mysql实战 1.ASCII(str) select ascii('a'); select ascii('ab'); select