即從字符串s中找出某個子串,此子串是長度一致的子串集合words的某種全排列,返回這些子串的開始位置。
如:s:"barfoofoobarthefoobarman",words:["bar","foo","the"];結果爲[6,9,12]。spa
假設原字符串s長度爲n,words中元素長度爲k,把k個字符當成一個總體來比較,即劃分k趟進行遍歷,再運用KMP思想進行匹配。時間複雜度約爲O(k*n)。
此處注意的是容器的選擇,基於二叉樹的容器存取並不如基於哈希的容器存取快。如下代碼採起了unordered_map做爲容器記錄前面的匹配狀況。code
typedef std::string _Type; class Solution { public: typedef std::unordered_map<_Type, int> UMAP; std::vector<int> findSubstring(const std::string& s, std::vector<std::string>& words) { std::vector<int> vec; int wsize = words.size(), ssize = s.size(); if (wsize == 0 || ssize == 0) return vec; UMAP all; for (int i = 0; i < wsize; ++i) ++(all[words[i]]); for (int mod = 0, len = words[0].size(); mod < len; ++mod) { UMAP had; for (int j = mod, start = mod, end = ssize - wsize * len; j <= end; ) { std::string tmpStr(s.substr(j, len)); j += len; UMAP::iterator it(all.find(tmpStr)); if (it == all.end()) { had.clear(); start = j; end = ssize - wsize * len; } else { if (it->second > had[tmpStr]) { ++(had[tmpStr]); if (j - start == wsize * len) { --(had[s.substr(start, len)]); vec.push_back(start); start += len; } else { end += len; } } else { for (int k = start; ; k += len) { std::string stmp(s.substr(k, len)); if (stmp == tmpStr) { start = k + len; break; } --(had[stmp]); end -= len; } } } } } return vec; } };
主要應用了KMP匹配的思想。leetcode