LintCode 1024 · Number of Matching Subsequences (binary search 好题)

1024 · Number of Matching Subsequences
Algorithms
Medium
Description
Given string S and a dictionary of words words, find the number of words[i] that is a subsequence of S.

Subsequence is different from substring. Subsequences may not be continuous.

All words in words and S will only consists of lowercase letters.
The length of S will be in the range of [1, 50000].
The length of words will be in the range of [1, 5000].
The length of words[i] will be in the range of [1, 50].
Example
Example 1:

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

Input: S = “dsahjpjauf”, words = [“ahjpjau”,“ja”,“ahbwzgqnuk”,“tnmlanowax”]
Output: 2
Tags
Company
Google
Related Problems

1263
Is Subsequence
Medium

解法1:binary search
这题跟Lintcode 1263比较像。但因为这题有多个word要跟s匹配,所以可以先做预处理把s中每个字符c对应的位置存到mp[c]对应的vector里面,然后对于每个word,我们只需要go thru string s, 注意这里我们可以对于每个word里面的字符c, 在mp[c]里面用binary search找大于它的最小位置,这样,我们go thru string s就可以跳着走了。这里我认为时间复杂度是O(nwlog(k)),这里n是words里面word的个数,w是每个word的平均长度,k是每个word里面的每个字符的平均重复数目。
如果我们用LintCode 1263的方法,那么时间复杂度是O(nwm)。这里m是s的长度。

class Solution {
public:
    /**
     * @param s: a string
     * @param words: a dictionary of words
     * @return: the number of words[i] that is a subsequence of S
     */
    int numMatchingSubseq(string &s, vector<string> &words) {
        int sizeS = s.size();
        int n = words.size();
        map<char, vector<int>> mp;
        for (int i = 0; i < sizeS; i++) {
            mp[s[i]].push_back(i);
        }
        int count = 0;
        for (auto word : words) {
            bool found = false;
            int indexW = 0, indexS = 0;
            while (indexS < sizeS) {
                char c = word[indexW];
                if (mp[c].empty()) break;
                int pos = binarySearch(mp[c], indexS);
                if (pos == -1) break;
                else indexW++;
                indexS = mp[c][pos] + 1;
            }
            if (indexW == word.size()) count++;
        }
        return count;
    }
private:
    int binarySearch(vector<int> &nums, int target) {
        int start = 0, end = nums.size() - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (nums[mid] < target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (nums[start] >= target) return start;
        if (nums[end] >= target) return end;
        return -1;
    }
};

你可能感兴趣的:(开发语言,leetcode,算法)