1. 程式人生 > >LeetCode題解:Substring with Concatenation of All Words

LeetCode題解: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.

Example 1:

Input:
  s =
"barfoothefoobarman", words = ["foo","bar"] Output: [0,9]

Example 2:

Input:
  s = "wordgoodstudentgoodword",
  words = ["word","student"]
Output: []

 

 

題目分析

 

這道題會給出一個字串以及包含著若干單詞的列表,我們的任務就是找出字串中所有包含所有單詞且只包含一次的子串的起始位置的下標。

值得注意的一點是,所有單詞的長度都是一致的。因此我們可以每次都往前移動這個長度來提取子串。為了讓查詢和比較更為高效,我選擇建立key為word且value為詞頻的map。

為了實時掌握當前正在查詢的子串的狀況,使用start和end分別標記子串的起始和結束,當end-start的值與單詞表中單詞的總長度一致時,就觸發找到條件。

為了避免runtime error,要檢查輸入的字串和列表是否為空。

 

程式碼實現

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
    	vector <int> result;
    	if (s.empty() || words.empty()) {
    		return result;
		}
        int word_length = words[0].size();
        int total_length = word_length*words.size();
        int start, end;
        map <string, int> dict;
        map <string, int> empty;
        string temp;
        for (auto str:words) {
        	//判斷字典裡面是否包含單詞
        	if (dict.count(str)) {
        		dict[str]++;
        	}
        	else {
        		dict[str] = 1;
        		empty[str] = 0;
        	}
        }
        map <string, int> ndict = empty;
        for (int i = 0; i < word_length && i + total_length <= s.size(); i++) {
        	start = i;
        	end = i;
        	ndict = empty;
        	while (start + total_length <= s.size()) {
        		temp = s.substr(end, word_length);
        		if (ndict.count(temp)) {
        			if (ndict[temp] < dict[temp]) {
        				ndict[temp]++;
        				end += word_length;
        			}
        			else {
        				ndict = empty;
        				start += word_length;
        				end = start;
        			}
        		}
        		else {
        			end += word_length;
        			start = end;
        			ndict = empty;
        		}
        		if (end-start == total_length) {
        			result.push_back(start);
        			ndict[s.substr(start, word_length)]--;
        			start += word_length;
        		}
        	}
        }
        return result;
    }
};