给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars。
假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。
注意:每次拼写时,chars 中的每个字母都只能用一次。
返回词汇表 words 中你掌握的所有单词的 长度之和。
示例:
输入:words = ["cat","bt","hat","tree"], chars = "atach"
输出:6
解释:
可以形成字符串 "cat" 和 "hat",所以答案是 3 + 3 = 6。
输入:words = ["hello","world","leetcode"], chars = "welldonehoneyr"
输出:10
解释:
可以形成字符串 "hello" 和 "world",所以答案是 5 + 5 = 10。
提示:
1 <= words.length <= 1000
1 <= words[i].length, chars.length <= 100
所有字符串中都仅包含小写英文字母
隐藏提示1:
Solve the problem for each string in words independently.
为每个字符串单独解决问题。
方法一:
思路
- 针对
words中的每个单词, 都去chars中查看是否拥有全部的字母 - 将可被
chars中拼出的字母加的一个数组(resultList)中去 - 遍历
resultList中的单词求得长度
代码
var countCharacters = function(words, chars) {
// - 针对 `words` 中的每个单词, 都去 `chars` 中查看是否拥有全部的字母
var checkWordCanBeFormed = (word, chars) => {
let copy = chars.split('')
for (let i = 0; i < word.length; i++) {
var s = word[i]
let index = copy.indexOf(s)
if (index >= 0) {
copy.splice(index, 1)
} else {
return false
}
}
return true
}
// - 将可被 `chars` 中拼出的字母加的一个数组(`resultList`)中去
let resultList = []
for (let i =0; i < words.length; i++) {
let word = words[i]
if (checkWordCanBeFormed(word, chars)) {
resultList.push(word)
}
}
// - 遍历 `resultList` 中的单词求得长度
let len = 0
resultList.forEach(word => len += word.length)
return len
};
// countCharacters(["cat","bt","hat","tree"], "atach")
// countCharacters(["hello","world","leetcode"], "welldonehoneyr")
隐藏提示2:
Now try to think in frequency of letters.
现在尝试思考字母的频率。
隐藏提示3:
Count how many times each character occurs in string chars.
计算每个字符在字符串字符中出现的次数。
隐藏提示4:
To form a string using characters from chars, the frequency of each character in chars must be greater than or equal the frequency of that character in the string to be formed.
要使用chars中的字符形成字符串,char中每个字符的频率必须大于或等于要形成的字符串中该字符的频率。
方法二:
思路
这一部分一般来自力扣的评论区, 我会去翻一些英文站的优秀解,或优秀评论出来。
关于频率这个的理解, 我一开始以为是要得到一个字典 { h: 1, e: 1, l: 2, o: 1 } 这样子, 直到看到一个回答使用 int[26] 数组。
- 声明一个长度为26(个英文字母)的数组
- 遍历 chars 里面的字母 并在相应的位置 +1
- 遍历 words 每个 word
- 遍历每个 word 的字符 并将 int[26] 数组位置的数减一 如果该处位置的数小于0 说明不 good 如果 good res+= word.length
代码
var countCharacters = function(words, chars) {
let res = 0
const count = (chars) => {
const root = 'a'.charCodeAt(0)
const counter = new Array(26).fill(0)
for (let index = 0; index < chars.length; index++) {
counter[chars.charCodeAt(index) - root]++
}
return counter
}
const contains = (charsCount, wordCount) => {
for (let i = 0; i < 26; i++) {
if (charsCount[i] < wordCount[i]) {
return false
}
}
return true
}
// 统计 chars 中字母出现的频率
const charsCount = count(chars)
words.forEach(word => {
const wordCount = count(word)
if (contains(charsCount, wordCount)) {
res += word.length
}
})
return res
};