力扣題目地址: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;
}
不忘初心,砥礪前行。