力扣题目地址:https://leetcode-cn.com/problems/find-words-that-can-be-formed-by-characters/
首先看题目:
给你一份『词汇表』(字符串数组) 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。
解决思路:
查字典法:最简单的方法,把每个单词都通过字母表比较一遍,如果这个单词可以通过字母表拼接出来,则记录长度,不能则继续下一个。
哈希表计数法:字母表中的字母以键值对的形式存在Map中;Key是字母,Value是字母的个数。然后对每一个单词也一样操作,然后比较每一个字符的两个Map中的Vaule值;如果这个单词要能通过字母表拼接出来,字母表Map中的值一定不小于单词表Map中的值。
代码实现:
/**
* 拼写单次
* https://leetcode-cn.com/problems/find-words-that-can-be-formed-by-characters/
* @param words
* @param chars
* @author Geyuxuan 2020-03-17 22:12:58
* @return int
*/
public int countCharacters(String[] words, String chars) {
//记录能够拼接的单词长度
int maxLength = 0;
//遍历单词
for (String word : words){
//单词转为char数组
char[] charWord = word.toCharArray();
//字母表转为char数组
char[] chars1 = chars.toCharArray();
//记录当前遍历的单词数组位置
int i;
for(i = 0; i < charWord.length;) {
//记录遍历的字母表的位置
int j;
for( j = 0; j < chars1.length; j++) {
//如果相等则说明找到一个对应字符
//跳出继续单词的下一个字符
if(charWord[i] == chars1[j]){
//将当前字母表字符置为0,防止重复读取
chars1[j] = 0;
//继续单词的下一个字符
i++;
//跳出循环
break;
}
}
//如果遍历到最后也没有对应上字符,跳出循环
//防止死循环
if(j == chars1.length){
break;
}
}
//如果单词遍历到最后一位,则说明该单词拼接完成
//计入拼接单词长度
if(i == charWord.length){
maxLength += word.length();
}
}
//返回单词长度
return maxLength;
}
/**
* 哈希表计数法
*
* @param words
* @param chars
* @author Geyuxuan 2020-03-17 23:31:34
* @return int
*/
public int countCharacters1(String[] words, String chars) {
//字母表存HashMap 并计数
Map<Character,Integer> charsMap = new HashMap<>(chars.length());
for(char c : chars.toCharArray()) {
if(charsMap.containsKey(c)){
charsMap.put(c,charsMap.get(c)+1);
}else{
charsMap.put(c,1);
}
}
//记录能够拼接的单词长度
int maxLength = 0;
for (String word : words){
//单词表存HashMap 并计数
Map<Character,Integer> wordMap = new HashMap<>(word.length());
for(char w : word.toCharArray()) {
if(wordMap.containsKey(w)){
wordMap.put(w,wordMap.get(w)+1);
}else{
wordMap.put(w,1);
}
}
//能否拼接单词标志
boolean check = true;
for (char w : word.toCharArray()){
//如果字母表中没有这个字符或者字符数小于单词表字符
//说明该单词无法拼接,修改标志,跳出循环
if(Objects.isNull(charsMap.get(w))
||charsMap.get(w) < wordMap.get(w)){
check = false;
break;
}
}
//判断是否能够拼接
if(check){
//计入拼接单词长度
maxLength += word.length();
}
}
//返回拼接单词长度
return maxLength;
}
不忘初心,砥砺前行。