【LeetCode】30. Substring with Concatenation of All Words

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:
S: "barfoothefoobarman"
L: ["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).

 

由于在vector中查找的复杂度是线性的,因此使用unordered_map存储L中所有单词,加快查找。

记每个单词word长度为len,字典L共有num个单词。

逐位扫描,以[0,n-len*num]分别作为起始点,判断后续的长度为len的num个word是否存在dict中,并且仅找到一次。

注意:

(1)判断某个元素word是否在map中,可以判断m[word]是否为0(int 的默认值)

(2)S.size()必须由unsigned int转为int型,若不然,当S长度较短时,减法结果会溢出。

i <= (int)S.size()-num*len

 

class Solution {
public:
    vector<int> findSubstring(string S, vector<string> &L) {
        vector<int> ret;
        int num = L.size();
        if(num < 1)
            return ret;
            
        int len = L[0].size();
        //save words into map to accelerate
        unordered_map<string, int> dict;
        for(int i = 0; i < num; i ++)
        {
            dict[L[i]] ++;
        }
        //attention: if no convertion to int, S.size()-num*len will overflow
        for(int i = 0; i <= (int)S.size()-num*len; i ++)
        {//start from i
            unordered_map<string, int> set;
            int j = 0;
            for(; j < num; j ++)
            {//search [S[i+j*len], S[i+(j+1)*len])
                string word = S.substr(i+j*len, len);
                if(dict[word] != 0 && set[word] < dict[word])
                {//in dict but not in set
                    set[word] ++;
                }
                else
                    break;
            }
            if(j == num)
            {//all words found once
                ret.push_back(i);
            }
        }
        return ret;
    }
};

posted @ 2014-12-18 21:37  陆草纯  阅读(223)  评论(0编辑  收藏  举报