问题:
给出一组字符串,求所有字符串共有的字符数组。
Example 1: Input: ["bella","label","roller"] Output: ["e","l","l"] Example 2: Input: ["cool","lock","cook"] Output: ["c","o"] Note: 1 <= A.length <= 100 1 <= A[i].length <= 100 A[i][j] is a lowercase letter
解法:
首先建立参照字符计数map
letcout
key=字符,value=该字符的出现计数
将A[0]的统计结果,存入letcout
然后对以后的A[i]
的每一个字符,比对letcout中是否有这个字符的计数>0
有的话,建立tmp字符计数map,将计数存入tmp的该字符计数中。
同时原参照计数letcout的计数--
A[i]遍历完成后,用tmp替换letcout成为新的参照计数,对A[i+1]再进行比对。
全部字符串比对完成后,letcout为最终所有字符串都含有的字符计数
将它转化为字符串数组res,返回。
♻️ 优化,相对于map,我们利用int [26]直接存放26个字母出现的次数。
代码参考:
1 class Solution { 2 public: 3 vector<string> commonChars(vector<string>& A) { 4 vector<string> res; 5 unordered_map<char, int> letcout; 6 for(int i=0; i<A[0].length(); i++){ 7 letcout[A[0][i]]++; 8 } 9 for(int i=1; i<A.size(); i++){ 10 unordered_map<char, int> tmp; 11 for(int j=0; j<A[i].length(); j++){ 12 auto cout=letcout.find(A[i][j]); 13 if(cout!=letcout.end() && cout->second!=0){ 14 cout->second--; 15 tmp[A[i][j]]++; 16 } 17 } 18 swap(letcout, tmp); 19 } 20 for(auto let:letcout){ 21 while(let.second!=0){ 22 res.push_back(string(1,let.first)); 23 let.second--; 24 } 25 } 26 return res; 27 } 28 };
优化后:
1 class Solution { 2 public: 3 vector<string> commonChars(vector<string>& A) { 4 vector<string> res; 5 int letcout[26]={0}; 6 for(char c:A[0]){ 7 letcout[c-'a']++; 8 } 9 for(int i=1; i<A.size(); i++){ 10 int tmp[26]={0}; 11 for(char c: A[i]){ 12 if(letcout[c-'a']>0){ 13 letcout[c-'a']--; 14 tmp[c-'a']++; 15 } 16 } 17 for(int j=0; j<26; j++){ 18 letcout[j]=tmp[j]; 19 } 20 } 21 for(int i=0; i<26; i++){ 22 while(letcout[i]>0){ 23 res.push_back(string(1,i+'a')); 24 letcout[i]--; 25 } 26 } 27 return res; 28 } 29 };