Leetcode 792. Number of Matching Subsequences

2 minute read

試著記得每次都要寫複雜度(?

題目

link

作法

一開始看到 tag 以為真的要寫 trie,後來才發現不用(用 trie 我也不會寫),用二分搜就可以了。

概念是先去紀錄 s 每個字母有出現在哪裡,然後去遍歷每個 word,對於 word 裡的每一個字母,我都要能在 s 裡面找到比前一個字母在 s 裡面的位置更後面的位置(好拗口),這樣才符合 subsequence of string。

舉例來說

1
2
s = "abcd"
words = ["ab", "cb"]

顯然對於 "ab" 來說,我可以在 s 裡面找到 1 跟 2 這兩個位置,所以他是對的,但對於 "cb" 來說,c 的第一個位置就是 3 了,而 3 後面沒有 b 所以他是錯的。

假設 s 長度是 $L$,$words$ 陣列長度是 $N$,每個 word 長度是 $l$,複雜度會是 $O(LNlog(l))$。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
public:
    int numMatchingSubseq(string s, vector<string>& words) {
        vector<vector<int> > ch(26);
        int n = s.length();
        for (int i = 0; i < n; i++)
        {
            ch[s[i] - 'a'].push_back(i);
        }
        
        int ans = 0;
        for (auto &word: words)
        {
            int id = -1;
            bool found = true;
            for (char c : word)
            {
                auto idx = upper_bound(ch[c - 'a'].begin(), ch[c - 'a'].end(), id);
                if (idx == ch[c - 'a'].end()) {
                    found = false;
                    break;
                }
                id = *idx;
            }
            if (found) ans++;
        }
        
        return ans;
    }
};