【力扣刷题】1160. 拼写单词

388 阅读1分钟

「这是我参与11月更文挑战的第 25 天,活动详情查看:2021最后一次更文挑战

原题链接

1160. 拼写单词 - 力扣(LeetCode) (leetcode-cn.com)

题目描述

给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars。

假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。

注意:每次拼写(指拼写词汇表中的一个单词)时,chars 中的每个字母都只能用一次。

返回词汇表 words 中你掌握的所有单词的 长度之和。

测试用例

示例 1:

输入:words = ["cat","bt","hat","tree"], chars = "atach"
输出:6
解释: 
可以形成字符串 "cat" 和 "hat",所以答案是 3 + 3 = 6

示例 2:

输入:words = ["hello","world","leetcode"], chars = "welldonehoneyr"
输出:10
解释:
可以形成字符串 "hello" 和 "world",所以答案是 5 + 5 = 10

参数限制

  • 1 <= words.length <= 1000
  • 1 <= words[i].length, chars.length <= 100
  • 所有字符串中都仅包含小写英文字母

分析

我们使用的字符串数组和字符串表,都是 小写字母

在字符串数组中的单词的各个字母,如果都可以在字符表中找到 (限定了字符表中的每个字符在尝试拼出这个单词的时候,只能使用一次),就可以认为这个单词是我们需要的,这个时候就需要将单词的长度记录,累计求和

代码

先统计字符串表中出现的字符以及出现的输出,使用 Object 进行存储

遍历单词表,在对单个单词做处理时,切割为字符表,统计其使用到的字符,以及需要使用的次数,需要随时终止遍历来提高效率 (当使用了字符串表里没有的字符时,或者是使用字符的频率超出了字符表中的记录,则可以通过立即终止此次遍历判断来提高效率)

var countCharacters = function(words, chars) {
    let obj = {};
    chars.split('').forEach(n => obj[n] = (obj[n] || 0) + 1)
    let count = 0;
    words.forEach(w => {
        let wobj = {};
        let flag = true;
        w = w.split('');
        for (let i = 0; i < w.length; i++) {
            let m = w[i];
            let c = (wobj[m] || 0) + 1
            if (obj[m] == undefined || obj[m] < c) {
                flag = false;
                break;
            }
            wobj[m] = c + 1;
        }
        if (flag) count += w.length;
    })
    return count;
};

image.png

感觉没有什么更好的解法了,最多通过抠细节提高一点点性能


今天的力扣刷题就分享到这里,感谢大家的阅读~