792. Number of Matching Subsequencesspa
Inverted Index + Binary Searchcode
Brute Force 會 TLE,時間複雜度爲 O(S*n + Σwords[i])。orm
能夠對S中每一個字符創建一個vector,保存其下標位置。這樣就能夠經過二分快速找到當前位置以後第一次出現的特定字符的下標。時間複雜度 O(S + Σ (words[i]*log(S)) )。blog
class Solution { public: int numMatchingSubseq(string S, vector<string>& words) { vector<vector<int>> pos(128); // pos[ch] is vector of indexes of ch in S for (int i=0;i<S.size();++i) pos[S[i]].push_back(i); int count=0; for (string word:words){ int prev=-1; for (char ch:word){ auto &index_vec=pos[ch]; auto it=upper_bound(index_vec.begin(),index_vec.end(),prev); if (it==index_vec.end()) goto outer; prev = *it; } ++count; outer:; } return count; } };
Inverted Index + Tableleetcode
若是要更快,能夠創建一個表 table[i][ch],記錄S的第i個位置後,第一次出現ch的下標。表的構建能夠從後往前掃描S,線性時間獲得。時間複雜度 O(S + Σwords[i]),犧牲空間換時間。get
class Solution { public: int numMatchingSubseq(string S, vector<string>& words) { // after_pos[i][ch] - the index of first ch after ith position of S vector<vector<int>> after_pos(S.size(),vector<int>(26,-1)); vector<int> first_pos(26,-1); // first_pos[ch] - the index of first ch in S for (int i=S.size()-1;i>=0;--i){ char ch=S[i]; for (int j=0;j<26;++j) after_pos[i][j] = first_pos[j]; first_pos[ch-'a'] = i; } int count=0; for (string word:words){ int i=0; int pos=first_pos[word[i++]-'a']; if (pos==-1) goto outer; while (i<word.size()){ pos = after_pos[pos][word[i++]-'a']; if (pos==-1) goto outer; } ++count; outer:; } return count; } };
Solution 的方法很像 Trie Tree,對全部word一塊兒處理。時間複雜度也是 O(S + Σwords[i])。string
https://leetcode.com/problems/number-of-matching-subsequences/solution/it
1055. Shortest Way to Form Stringio
和上一題如出一轍,一樣能夠二分或者直接建表作。table
class Solution { public: int shortestWay(string source, string target) { vector<vector<int>> pos(26); // pos[ch] - vector of indexes for (int i=0;i<source.size();++i) pos[source[i]-'a'].push_back(i); int count=0; int i=0, prev=-1; while (i<target.size()){ char ch=target[i]; auto &index_vec=pos[ch-'a']; if (index_vec.size()==0) return -1; auto it=upper_bound(index_vec.begin(),index_vec.end(),prev); if (it==index_vec.end()){ prev = -1; ++count; }else{ prev = *it; ++i; } } ++count; return count; } };