LeetCode 1160. 拼写单词

55 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第29天,点击查看活动详情

1.描述

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
  • 所有字符串中都仅包含小写英文字母

2.分析

根据题目我们知道的信息有

每次拼写时,chars中的每个字母只能使用一次, 用chars中的字符拼写出words中某个单词,就认为掌握了这个单词

也就是说只要words中某个单词中的字母出现次数不超过chars中每个字母出现的次数,就算掌握了。 基于上面的思路,我们可以使用hash表来存储chars中每个字母出现的次数,以key-value的形式储存

遍历单词表中的每个单词,然后使用上面生成的hash表去查找存不存在这个字母,存在就减去1次,如果最后是负数 就不符合条件

最后将长度相加,就是我们要的答案

3.AC代码

var countCharacters = function(words, chars) {
    let charsMap = new Map()
    let res = 0

    for (let s of chars) {
        charsMap.set(s, charsMap.has(s) ? charsMap.get(s) + 1 : 1)
    }

    for (let w of words) {
        if (help(w, new Map(charsMap))) {
            res += w.length
        }
    }
    return res
};

function help(w, hash) {
    for (let i of w) {
        if (!hash.has(i)) {
            return false
        } else {
            hash.set(i, hash.get(i) - 1)
            if (hash.get(i) < 0) {
                return false
            }
        }
    }
    return true
}

参考

记得第一次看别人用int[26]的时候被惊艳到了 - 拼写单词 - 力扣(LeetCode) (leetcode-cn.com)