LeetCode30. 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 words exactly once and without any intervening characters.

s: “barfoothefoobarman”
words: [“foo”, “bar”]
You should return the indices: [0,9]. (order does not matter).

words里面是可能重复的。

初始做法,使用多重映射multimap,很朴素的做法,超时:

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        vector<int> vec;
        if(words.empty()) return vec;

        int num = words.size();
        int len = words[0].size();

        multimap<string, int> mp;
        for(int i = 0; i < words.size(); ++i) mp.insert(pair<string, int>(words[i], i));

        for(int i = 0; i < s.size() - num * len + 1; ++i){
            string str = s.substr(i, num * len);
            int k[num];
            memset(k, 0, sizeof(k));
            for(int j = 0; j < str.size(); j += len){
                string tmp = str.substr(j, len);
                if(mp.find(tmp) != mp.end()){
                    pair <multimap<string,int>::iterator, multimap<string,int>::iterator> ret;
                    ret = mp.equal_range(tmp);

                    bool ok = false;
                    for (multimap<string,int>::iterator it=ret.first; it!=ret.second; ++it){
                        if(k[it->second] == 0){
                            if(j == str.size() - len) vec.push_back(i);
                            k[it->second] = 1;
                            ok = true;
                            break;
                        }
                    }
                    if(!ok) break;
                }
                else break;
            }
        }
        return vec;
    }
};

后来,改用unordered_map,使用1个映射记录words每个单词的数量,再使用一个映射记录字符串里各单词出现次数,如果出现次数大于对应单词数量,则说明不匹配。

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        vector<int> vec;
        if(words.empty()) return vec;

        int num = words.size();
        int len = words[0].size();
        unordered_map<string, int> mp;

        for(string word : words)
            mp[word]++;
        for(int i = 0; i < s.size() - num * len + 1; ++i){
            string str = s.substr(i, num * len);
            unordered_map<string, int> mp2;
            for(int j = 0; j < str.size(); j += len){
                string word = str.substr(j, len);
                if(mp.find(word) != mp.end()){
                    mp2[word]++;
                    if(mp2[word] > mp[word]) break;
                }
                else break;
                if(j == str.size() - len) vec.push_back(i);
            }
        }
        return vec;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值