【一看就会一写就废 指间算法】可以输入的最大单词数 —— 哈希表

41 阅读2分钟

指尖划过的轨迹,藏着最细腻的答案~

题目:

键盘出现了一些故障,有些字母键无法正常工作。而键盘上所有其他键都能够正常工作。

给你一个由若干单词组成的字符串 text,单词间由单个空格组成(不含前导和尾随空格);另有一个字符串 brokenLetters ,由所有已损坏的不同字母键组成,返回你可以使用此键盘完全输入的单词数目。

示例 1:

输入:text = "hello world", brokenLetters = "ad"
输出:2
解释:可以完全输入 "hello" 和 "world" ,由于这两个单词都不包含损坏的字母键。

示例 2:

输入:text = "leet code", brokenLetters = "lt"
输出:1
解释:可以完全输入 "code" ,因为这个单词不包含损坏的字母键。
但是无法完全输入 "leet" ,因为其中的 'l' 和 't' 都已损坏。

示例 3:

输入:text = "leet code", brokenLetters = "e"
输出:0
解释:无法完全输入任何单词,因为所有单词都至少包含一个损坏的字母键。

提示:

1 <= text.length <= 10410^4
0 <= brokenLetters.length <= 26
text 由若干用单个空格分隔的单词组成,且不含任何前导和尾随空格
每个单词仅由小写英文字母组成
brokenLetters 由 互不相同 的小写英文字母组成

分析:

题目意思即为text中以空格分隔的单词不能出现brokenLetters中的字符。

我们遍历text,对于c=text[i]怎样快速的判断其是否在brokenLetters中出现呢?我们可以使用哈希表来预先处理一下brokenLetters,然后我们就可以在O(1)的时间复杂度内判断c是否在brokenLetters中出现。

注意,由于text前后都没有空格,因此在遍历时为了保证最后一个单词也可以复用空格判断逻辑,我们人为在text最后面插入一个空格。

AC代码:

class Solution {
public:
    int canBeTypedWords(string text, string brokenLetters) {
        int hash[26] = {0};
        for (int i = 0; i < brokenLetters.size(); i++) {
            char c = brokenLetters[i];
            hash[c - 'a'] = 1;
        }

        int ans = 0;
        bool flag = false;
        text.push_back(' ');
        for (int i = 0; i < text.size(); i++) {
            while(i < text.size() && flag && text[i] != ' ') {
                i++;
            }

            if (text[i] == ' ') {
                if (!flag) {
                    ans ++;
                }
                flag = false;
                continue;
            }

            if (hash[text[i] - 'a']) {
                flag = true;
            }
        }

        return ans;
    }
};