题目来源
题目描述
题目解析
本题可以理解为求每个字符串之间字符数量的交集,以示例1为例:
输入:[“bella”,“label”,“roller”]
输出:[“e”,“l”,“l”]
我们知道第一个字符串的字符数量列表为:
b 1
e 1
l 2
a 1
第二个字符串的字符数量列表为:
l 2
a 1
b 1
e 1
第三个字符串的字符数量列表为:
r 2
o 1
l 2
e 1
这三个求交集后的结果为:
e 1
l 2
理解题目是关键
计数
根据题目的要求,如果字符c
在所有字符串中均出现了k
次以及以上,那么最终da’an1中需要包含k
个c
。因此,我们可以使用minfreq[c]
存储字符c
在所有字符串中出现次数的最小值。
我们可以依次遍历每一个字符串。当我们遍历到字符串s
时,我们使用freq[c]
统计s
中每一个字符c
出现的次数。在统计完成之后,我们再将每一个minfreq[c]
更新为其本身与freq[c]
的较小值。这样一来,当我们遍历完所有字符串之后,minfreq[c]
就存储了字符c
在所有字符串中出现的最小值。
由于题目保证了所有的字符均为小写字母,因此我们可以用长度为 2626 的数组分别表示 minfreq
以及 freq
在构造最终的答案时,我们遍历所有的小写字母 cc,并将minfreq[c]
个 c
添加进答案数组即可。
class Solution {
public:
vector<string> commonChars(vector<string>& words) {
std::vector<int> minfreq(26, INT_MAX);
std::vector<int> freq(26);
for(const std::string & word : words){
std::fill(freq.begin(), freq.end(), 0);
for(char ch : word){
++freq[ch - 'a'];
}
for (int i = 0; i < 26; ++i) {
minfreq[i] = std::min(minfreq[i], freq[i]);
}
}
std::vector<std::string> ans;
for (int i = 0; i < 26; ++i) {
for (int j = 0; j < minfreq[i]; ++j) {
std::string s(1, i + 'a'); // char -> string
ans.emplace_back(s);
}
}
return ans;
}
};
class Solution {
public List<String> commonChars(String[] A) {
List<String> ans = new ArrayList<>();
int [] arr = new int[26];
char[] v = A[0].toCharArray();
for (char c : v){
arr[c - 'a'] ++;
}
for (int i = 1; i < A.length; i++){
int [] brr = new int[26];
for (char c : A[i].toCharArray()){
brr[c - 'a'] ++;
}
for (int j = 0; j < arr.length; j++){
if (brr[j] < arr[j]){
arr[j] = brr[j];
}
}
}
for (int j = 0; j < arr.length; j++){
while (arr[j] != 0){
ans.add(String.valueOf((char)('a' + j)));
arr[j]--;
}
}
return ans;
}
}