30串聯所有單詞的子串
阿新 • • 發佈:2020-12-23
技術標籤:leetCode 題目leetcode字串第30題目c++
30串聯所有單詞的子串
題目難度:困難
題目要求:
給定一個字串s和一些長度相同的單詞words。找出 s 中恰好可以由words 中所有單詞串聯形成的子串的起始位置。
注意子串要與words 中的單詞完全匹配,中間不能有其他字元,但不需要考慮words中單詞串聯的順序。
示例 1:
輸入:
s = "barfoothefoobarman",
words = ["foo","bar"]
輸出:[0,9]
解釋:
從索引 0 和 9 開始的子串分別是 "barfoo" 和 "foobar" 。
示例 2:
輸入:
s = "wordgoodgoodgoodbestword",
words = ["word","good","best","word"]
輸出:[]
解題思路:
首先考慮的當然是匹配問題,如果常規的去匹配字串,需要大量的匹配的時間,於是採用hashmap的方式,這樣就可以查詢每次的複雜度都是1了。然後每個字串都是數量相等的,這樣就可以拆分,可以想到雙指標。然後就是返回的東西了。細節比較多。
vector<int> findSubstring(string s, vector<string>& words) { if (words.size() == 0) return{}; unordered_map<string, int> wordcnt; for (auto& w : words) { wordcnt[w]++; } int len = words[0].size(); vector<int> ans; for (int i = 0; i < len; i++) { int left = i; int right = left; int cnt = 0; unordered_map<string, int> window; while (left + words.size() * len <= s.size()) { string temp = ""; while (cnt < words.size()) { temp = s.substr(right, len); if (wordcnt.find(temp) == wordcnt.end() || window[temp] >= wordcnt[temp]) break; window[temp]++; cnt++; right += len; } if (window == wordcnt) { ans.push_back(left); } if (wordcnt.find(temp) != wordcnt.end()) { window[s.substr(left, len)]--; cnt--; left += len; } else { right += len; left = right; cnt = 0; window.clear(); } } } return ans; }