给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars。
假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。
注意:每次拼写时,chars 中的每个字母都只能用一次。
返回词汇表 words 中你掌握的所有单词的 长度之和。
输入:words = ["cat","bt","hat","tree"], chars = "atach"
输出:6
解释:
可以形成字符串 "cat" 和 "hat",所以答案是 3 + 3 = 6。
比较容易想到的一个解法就是:先统计字母表中每个字符的数量,然后遍历整个词汇表中的每个单词,看是否能够拼出每个单词。
统计每个字符的数量就是使用map,但是题目中说只有小写字母,就可以使用vector来代替map。
还有个问题就是如何检查能否拼出每个单词?如果字母表中这个单词的数量大于这个单词所需要的数量,则能拼出。
具体代码如下:
解法一:
class Solution {
// 检查字母表的字母出现次数是否覆盖单词的字母出现次数
bool test(vector<int> freq_c, vector<int> freq_s){
for(int i = 0; i < freq_s.size(); i++){
if(freq_s[i] > freq_c[i]){
return false;
}
}
return true;
}
public:
int countCharacters(vector<string>& words, string chars) {
vector<int> freq_c(26,0); // 统计字母表的字母出现次数
for(int i = 0; i < chars.size(); i++){
freq_c[chars[i]-'a']++;
}
int res = 0;
for(int i = 0; i < words.size(); i++){
vector<int> freq_s(26,0); // 统计单词的字母出现次数
for(int j = 0; j < words[i].size(); j++){
freq_s[words[i][j] - 'a']++;
}
if(test(freq_c,freq_s)){
res += words[i].size();
}
}
return res;
}
};
解法二:
class Solution {
public:
int countCharacters(vector<string>& words, string chars) {
vector<int> freq_c(26,0); // 统计字母表的字母出现次数
for(int i = 0; i < chars.size(); i++){
freq_c[chars[i]-'a']++;
}
int res = 0;
for(int i = 0; i < words.size(); i++){
vector<int> freq_s = freq_c; //复制一份
bool flag = true;
for(int j = 0; j < words[i].size(); j++){
if(freq_s[words[i][j] - 'a'] == 0){
flag = false;
break;
}
freq_s[words[i][j] - 'a']--;
}
if(flag){
res += words[i].size();
}
}
return res;
}
};