792. Number of Matching Subsequences

1. Description

Given a string s and an array of strings words, return the number of words[i] that is a subsequence of s.
A subsequence of a string is a new string generated from the original string with some characters (can be none) deleted without changing the relative order of the remaining characters.

  • For example, “ace” is a subsequence of “abcde”.

2. Example

Example 1:
Input: s = “abcde”, words = [“a”,“bb”,“acd”,“ace”]
Output: 3
Explanation: There are three strings in words that are a subsequence of s: “a”, “acd”, “ace”.

Example 2:
Input: s = “dsahjpjauf”, words = [“ahjpjau”,“ja”,“ahbwzgqnuk”,“tnmlanowax”]
Output: 2

3. Constraints

  • 1 <= s.length <= 5 * $10^4$
  • 1 <= words.length <= 5000
  • 1 <= words[i].length <= 50
  • s and words[i] consist of only lowercase English letters.

4. Solutions

m = words.size(), n = words[0].size(), o = str.size()
Time complexity: O(mlogo) // not related to n? because n is always less than o Space complexity: O(n)

class Solution {
public:
    int numMatchingSubseq(const string &str, const vector<string> &words) {
        unordered_map<char, vector<int>> letter_indices;
        for (int i = 0; i < str.size(); ++i) {
            letter_indices[str[i]].push_back(i);
        }

        int matching_count = 0;
        for (const auto &word : words) {
            if (word.size() > str.size()) {
                continue;
            }
            unordered_map<char, int> letter_left_index;

            int last_index = -1;
            for (auto letter : word) {
                auto it = upper_bound(
                    letter_indices[letter].begin() +
                        (letter_left_index.find(letter) == letter_left_index.end()
                             ? 0
                             : letter_left_index[letter]),
                    letter_indices[letter].end(),
                    last_index);
                if (it == letter_indices[letter].end()) {
                    goto pass;
                } else {
                    letter_left_index[letter] = it - letter_indices[letter].begin();
                    last_index = *it;
                }
            }

            ++matching_count;
        pass:;
        }

        return matching_count;
    }
};
comments powered by Disqus