我在Leetcode上遇到了一个名为“ Number of Matching Subsequences”的问题。给您一个字符串S和一个较小字符串的向量,您必须找出多少个较小的字符串是S的子字符串。(不一定是连续的子字符串。)
我以某种方式编写了代码,尽管可以正常工作,但Leetcode上的编译器却超时了。其他人编写的代码与我的几乎相同,但是并没有超时。我想知道是什么让他更快。这是我的:
class Solution {
public:
int numMatchingSubseq(string S, vector<string>& words) {
int count = 0;
vector<set<int>> Svec (26); // keep track of the indices where characters were seen in S
for (int i = 0; i < S.length(); ++i) Svec[S[i] - 'a'].insert(i);
for (auto & w : words) { // loop over words and characters within words, finding the soonest the next character appears in S
bool succeeded = true;
int current_index = -1;
for (auto & c : w) {
set<int> & c_set = Svec[c - 'a'];
auto it = upper_bound(begin(c_set), end(c_set), current_index);
if (it == end(c_set)) {
succeeded = false;
break;
}
current_index = *it;
} // loop over chars
if (succeeded) count++;
} //loop over words
return count;
}
};
int main() {
string S = "cbaebabacd";
vector<string> words {"abc", "abbd", "bbbbd"};
Solution sol;
cout << sol.numMatchingSubseq(S, words) << endl;
return 0;
}
输出
2
Program ended with exit code: 0
他的解决方案不是将索引存储在vector<set<int>>
中,而是存储在vector<vector<int>>
中。我不明白为什么会有很大的不同。
int numMatchingSubseq (string S, vector<string>& words) {
vector<vector<int>> alpha (26);
for (int i = 0; i < S.size (); ++i) alpha[S[i] - 'a'].push_back (i);
int res = 0;
for (const auto& word : words) {
int x = -1;
bool found = true;
for (char c : word) {
auto it = upper_bound (alpha[c - 'a'].begin (), alpha[c - 'a'].end (), x);
if (it == alpha[c - 'a'].end ()) found = false;
else x = *it;
}
if (found) res++;
}
return res;
}
答案 0 :(得分:1)
效率低下:
Blob URL
请参见these std::upper_bound()
docs中的注释:
对于非LegacyRandomAccessIterators,迭代器增量的数量是线性的。
您应该使用:
upper_bound(begin(c_set), end(c_set), current_index)