[LeetCode] 030. Substring with Concatenation of All Words (Hard) (C ++/Java), leetcode
Index: [LeetCode] Leetcode index (C ++/Java/Python/SQL)
Github: https://github.com/illuz/leetcode
030. Substring with Concatenation of All Words (Hard)
Link:
Title: https://oj.leetcode.com/problems/substring-with-concatenation-of-all-words/
Code (github): https://github.com/illuz/leetcode
Question:
Given a string S and a word list, the word length is the same, and the substring of all S is found. The substring is composed of all words and returns the starting position of the substring.
Analysis:
Obviously, each substring is composed of all words and has a certain length. Therefore, you can enumerate the substrings directly, split them, and then use map for determination.
The complexity of this algorithm is O (n * m). In fact, there are several cool O (n) algorithms:
Here we use C ++ to implement the O (n * m) algorithm and Java to implement the 1 algorithm.
Code:
C ++:
class Solution {public: vector<int> findSubstring(string S, vector<string> &L) {map<string, int> words;map<string, int> curWords;vector<int> ret;int slen = S.length();if (!slen || L.empty()) return ret;int llen = L.size(), wlen = L[0].length();// record the current words mapfor (auto &i : L)++words[i];// check the [llen * wlen] substringfor (int i = 0; i + llen * wlen <= slen; i++) {curWords.clear();int j = 0;// check the wordsfor (j = 0; j < llen; j++) {string tmp = S.substr(i + j * wlen, wlen);if (words.find(tmp) == words.end())break;++curWords[tmp];if (curWords[tmp] > words[tmp])break;}if (j == llen)ret.push_back(i);}return ret; }};
Java:
public class Solution { public List<Integer> findSubstring(String S, String[] L) { List<Integer> ret = new ArrayList<Integer>(); int slen = S.length(), llen = L.length; if (slen <= 0 || llen <= 0) return ret; int wlen = L[0].length(); // get the words' map HashMap<String, Integer> words = new HashMap<String, Integer>(); for (String str : L) { if (words.containsKey(str)) { words.put(str, words.get(str) + 1); } else { words.put(str, 1); } } for (int i = 0; i < wlen; ++i) { int left = i, count = 0; HashMap<String, Integer> tmap = new HashMap<String, Integer>(); for (int j = i; j <= slen - wlen; j += wlen) { String str = S.substring(j, j + wlen); if (words.containsKey(str)) { if (tmap.containsKey(str)) { tmap.put(str, tmap.get(str) + 1); } else { tmap.put(str, 1); } if (tmap.get(str) <= words.get(str)) { count++; } else { // too many words, push the 'left' forward while (tmap.get(str) > words.get(str)) { String tmps = S.substring(left, left + wlen); tmap.put(tmps, tmap.get(tmps) - 1); if (tmap.get(tmps) < words.get(tmps)) { // if affect the count count--; } left += wlen; } } // get the answer if (count == llen) { ret.add(left); // it's better to push forward once String tmps = S.substring(left, left + wlen); tmap.put(tmps, tmap.get(tmps) - 1); count--; left += wlen; } } else { // not any match word tmap.clear(); count = 0; left = j + wlen; } } } return ret; }}