roufoo的博客

纸上学来终觉浅 绝知此事要躬行

Leetcode-30: Substring with Concatenation of All Words

这题思路不算太难,但要给出比较快速的算法也不容易。

我本来决定用set,但发现题目的本意是允许words[]里面有多个重复字符串,后来决定用multiset,但set和multiset都没有count,不能单减count, 只能erase。但multiset的erase(string)会删掉所有的相同string,除非用iterator删。最后决定用unordered_map,因为它可以有count,并且用hash,比map快些。

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <algorithm>

using namespace std;

vector<int> findSubstring(string s, vector<string>& words) {
    vector<int> sol;

    if (!words.size() || !s.size()) return sol;
    int wordLen=words[0].size();
    int wordNum=words.size();

    unordered_map<string, int> mm_orig, mm;
    for(int i=0; i<wordNum; ++i)
        mm_orig[words[i]]++;

    int totalLength = wordLen*wordNum < s.size() ? wordLen*wordNum : s.size();
    int runLength = (int)s.size()-totalLength+1;
    for (int i=0; i<runLength; ++i) {
        string subStrs=s.substr(i, totalLength);
        int hitCount=0;
        mm = mm_orig;
        for (int j=0; j<subStrs.size(); j+=wordLen) {
            string subString = subStrs.substr(j, wordLen);

            if (mm[subString]>0) {
                mm[subString]--;
                hitCount++;
            }else{
                break;
            }
        }

        if (hitCount==wordNum)
            sol.push_back(i);
    }

    return sol;
}
int main()
{
    //string s="barfoothefoobarman";
    //string s="a";
    string s="wordgoodgoodgoodbestword";

    //vector<string> words={"foo", "bar"};
    //vector<string> words={"a", "a"};
    vector<string> words={"word","good","best","good"};

    vector<int> sol = findSubstring(s, words);

    for (auto n : sol) cout<<n<<" ";

    return 0;
}

我的解法的时间复杂度为O(nm), 其中n为s的长度,m为words[]内所有字符串相加的长度。比较慢。在Leetcode官网上有一个O(n)的解法,我看了一下,思路比较好,其代码如下。

  // travel all the words combinations to maintain a window
    // there are wl(word len) times travel
    // each time, n/wl words, mostly 2 times travel for each word
    // one left side of the window, the other right side of the window
    // so, time complexity O(wl * 2 * N/wl) = O(2N)
    vector<int> findSubstring(string S, vector<string> &L) {
        vector<int> ans;
        int n = S.size(), cnt = L.size();
        if (n <= 0 || cnt <= 0) return ans;

        // init word occurence
        unordered_map<string, int> dict;
        for (int i = 0; i < cnt; ++i) dict[L[i]]++;

        // travel all sub string combinations
        int wl = L[0].size();
        for (int i = 0; i < wl; ++i) {
            int left = i, count = 0;
            unordered_map<string, int> tdict;
            for (int j = i; j <= n - wl; j += wl) {
                string str = S.substr(j, wl);
                // a valid word, accumulate results
                if (dict.count(str)) {
                    tdict[str]++;
                    if (tdict[str] <= dict[str]) 
                        count++;
                    else {
                        // a more word, advance the window left side possiablly
                        while (tdict[str] > dict[str]) {
                            string str1 = S.substr(left, wl);
                            tdict[str1]--;
                            if (tdict[str1] < dict[str1]) count--;
                            left += wl;
                        }
                    }
                    // come to a result
                    if (count == cnt) {
                        ans.push_back(left);
                        // advance one word
                        tdict[S.substr(left, wl)]--;
                        count--;
                        left += wl;
                    }
                }
                // not a valid word, reset all vars
                else {
                    tdict.clear();
                    count = 0;
                    left = j + wl;
                }
            }
        }

        return ans;
    }
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/roufoo/article/details/79959250
文章标签: Leetcode
个人分类: algorithm-design
上一篇Leetcode-19: Remove Nth Node From End of List
下一篇Leetcode-155: Min Stack
想对作者说点什么? 我来说一句

oracle中 substring函数的使用

2013年06月21日 1KB 下载

java中截取带汉字的字符串

2011年07月04日 1KB 下载

words words words

2015年02月04日 454B 下载

Bag of visual words 详解及例程

2011年04月08日 13.74MB 下载

截取文件的文件名

2011年10月16日 1KB 下载

DFA的原理文章

2013年08月25日 127KB 下载

没有更多推荐了,返回首页

关闭
关闭