题目:给你一份【词汇表】(字符串数组) 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 。
分析:
根据题目意思,要从字符串数组中找已到掌握的字符串 s ,这个字符串必须满足以下两个条件:
- 字符串 s 中的每一个字符 s[i] 都要出现在 chars 中。
- 由于每次拼写时,chars 中的每个字母都只能用一次。因此还需要 s 中每个字符出现的次数 小于或等于 chars 中每个字符出现的次数。
因此,需要统计字符串数组中每个字符串是否满足以上两点,满足的话,就累计长度之和。可以使用 map 来计算每个字符串出现的字符已经出现的次数。具体实现细节如下:
(1)用 map 存储 chars 中的每个字符以及每个字符出现的次数。
(2)对于字符串数组 words 中的每一个字符串 words[i] ,也用 map 来存储 words[i] 中的每个字符以及每个字符出现的次数。
(3)两个 map 的内容进行比较,要同时满足上述两个条件才累加长度。
实现代码如下:
func countCharacters(words []string, chars string) int {
var res int
//定义一个mapper,用来村存储 chars 中的字符以及其出现次数
var mapper map[byte]int
mapper = make(map[byte]int) //一定要make
var i, j int
//编译整个chars,记录其信息存储在mapper中
for i = 0; i < len(chars); i++ {
mapper[chars[i]]++
}
var flag int
for i = 0; i < len(words); i++ {
flag = 0
/*对字符串数组words中的每一个字符串,定义一个wordsMapper,
记录每个字符串出现的字符和次数*/
var wordsMapper map[byte]int
wordsMapper = make(map[byte]int)
//第一次编译words[i],获取words[i]的信息,将其存储在wordsMapper中
for j = 0; j < len(words[i]); j++ {
wordsMapper[words[i][j]]++
}
/*第二次遍历words[i]*/
for j = 0; j < len(words[i]); j++ {
v1, ok := mapper[words[i][j]] //判断words[i]中的每个字符是否在chars中出现过
if ok == false { //如果没有出现过,当前字符串就不满足题意
flag = 1
break
}
//如果满足,继续判断当前字符出现的次数v2是否大于chars中该字符的出现次数
v2, _ := wordsMapper[words[i][j]]
if v1 < v2 {//如果是,当前字符串不满足题意。
flag = 1
break
}
}
if flag == 0 { //如果两个条件均满足,则进行长度累加
res = res + len(words[i])
}
}
return res
}