0x01.問題
給你一份『詞彙表』(字符串數組) words 和一張『字母表』(字符串) chars。
假如你可以用 chars 中的『字母』(字符)拼寫出 words 中的某個『單詞』(字符串),那麼我們就認爲你掌握了這個單詞。
注意:每次拼寫時,chars 中的每個字母都只能用一次。
返回詞彙表 words 中你掌握的所有單詞的 長度之和。
輸入示例:words = ["cat","bt","hat","tree"], chars = "atach"
輸出示例:6
解釋:可以形成字符串 "cat" 和 "hat",所以答案是 3 + 3 = 6。
提示:
1 <= words.length <= 1000
1 <= words[i].length, chars.length <= 100
所有字符串中都僅包含小寫英文字
C++函數形式爲 int countCharacters(vector<string>& words, string chars)
0x02.分析問題
題目的需求其實很簡單,只需要字母表中的相應字符詞彙表每個單詞的相應字符要多,就能認定掌握單詞。
既然這樣,字母表的作用其實就是提供相應字符的數量,僅此而已,然後對於字符串,遍歷每個字符是必須的,遍歷每個字符的時候,都考慮一下字母表中的字符是否還足夠,不足夠就直接退出循環,足夠就一直遍歷下去,如果能遍歷完,說明這個單詞可以掌握。
我們的問題就簡化到了如何記錄相應字符的個數,毫無疑問,第一思路肯定是哈希表,的確,用哈希表也可以很快的解決,但是,有了昨天的前車之鑑,我開始思考更加高效的方法。
用哈希表肯定時間還是會稍長一點,我們可以用一個數組仿造出哈希表,因爲這些字母都是有規律的,無非就是0-26個連續字符,而且在ASCII表中還是連續存在的,所以我們就可以直接拿下標當鍵值用,這樣訪問的效率非常高。
這就是用數組仿造的哈希表。
0x03.解決代碼
class Solution {
public:
int countCharacters(vector<string>& words, string chars) {
int count=0,i,j;
vector<int> Table(26,0);
for(int i=0;i<chars.size();i++){
Table[chars[i]-'a']++;
}
for(i=0;i<words.size();i++){
vector<int> Table1(Table);
for(j=0;j<words[i].size();j++){
if(Table1[words[i][j]-'a']==0) break;
else Table1[words[i][j]-'a']--;
}
if(j==words[i].size()) count+=words[i].size();
}
return count;
}
};
注意每次開始遍歷一個字符串的時候,要初始化表中的內容。
0x04.複雜度分析
- 時間複雜度主要由遍歷字符串產生,遍歷字符串的每個字符可以忽略不計,整體來說是 O(N)。
- 空間複雜度主要由兩個數組產生,最大空間爲52,可以忽略不計,認爲是 O(1)。
- 這應該算是最高效的方法了,不能再繼續優化。
ATFWUS --Writing By 2020--03--17