問題描述
給你一份『詞彙表』(字符串數組) 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。
提示:
1.1 <= words.length <= 1000
2.1 <= words[i].length, chars.length <= 100
3.所有字符串中都僅包含小寫英文字母
題解
說下讓我看起來非常驚豔的解法,通過26位ASCII編碼屬性計算每個字母的count數量,然後通過words
循環內的元素和chars
數組進行對比,最後return滿足條件的長度就好了,廢話不多說,上代碼:
/**
*
* @param words
* 單詞數組
* @param chars
* 已有字母
* @return
*/
public int countCharacters(String[] words, String chars) {
int[] originalCounter = counter(chars);
int length = 0;
for (int i = 0; i < words.length; i++) {
String word = words[i];
int[] wordCounter = counter(word);
boolean isSuccess = true;
for (int j = 0; j < 26; j++) {
if (originalCounter[j] < wordCounter[j]) {
isSuccess = false;
break;
}
}
if (isSuccess) {
length += word.length();
}
}
return length;
}
/**
* 將字符轉爲索引對應的ASCII碼值
*
* @param word
* @return
*/
private int[] counter(String word){
int[] counter = new int[26];
char[] charArray = word.toCharArray();
for (int j = 0; j < charArray.length; j++) {
counter[charArray[j] - 'a'] ++; // 這裏是關鍵哦
}
return counter;
}
思路還是挺好的,但是上面的代碼有些冗餘有沒有發現,正好通過這次刷題,學到了continue 標籤;
這種寫法,意義在於使內層循環break,外層繼續下次遍歷,代碼如下:
public int countCharacters(String[] words, String chars) {
int[] ch_array = new int[26];
for (char c : chars.toCharArray()) {
++ch_array[c - 'a'];
}
int length = 0;
search:
for (String word : words) {
int[] word_count = new int[26];
for (char c : word.toCharArray()) {
if (++word_count[c - 'a'] > ch_array[c - 'a']) {
continue search;
}
}
length += word.length();
}
return length;
}