题目描述:
给定仅有小写字母组成的字符串数组 A,返回列表中的每个字符串中都显示的全部字符(包括重复字符)组成的列表。例如,如果一个字符在每个字符串中出现 3 次,但不是 4 次,则需要在最终答案中包含该字符 3 次。
你可以按任意顺序返回答案。
示例 1:
输入:["bella","label","roller"]
输出:["e","l","l"]
先放着原题不做,先试试做一个简单版本的该题,只需要求出重复出现的字母即可,那么久可以很轻易的想到,利用一个长度为26的数组保存字母出现的个数,用另一个长度为26的数组来存储标识位,用于防止出现由于一个字符串中单个字母出现多次导致计数错误的情况,那么代码也就很容易写出:
class Solution {
public List<String> commonChars(String[] A) {
int[] cur = new int[26];
List<String> list = new ArrayList<>();
for (int i = 0; i < A.length; i++) {
int[] flag = new int[26];
char[] chars = A[i].toCharArray();
for (int j = 0; j < chars.length; j++) {
int num = chars[j]-97;
if (flag[num]==0){
cur[num]++;
flag[num]=1;
}
}
}
for (int i = 0; i < cur.length; i++) {
if (cur[i]==3){
String tmp = String.valueOf((char)(i+97));
list.add(tmp);
}
}
return list;
}
}
现在来看看原题的要求,
如果一个字符在每个字符串中出现 3 次,但不是 4 次,则需要在最终答案中包含该字符 3 次
所以,就需要考虑,一个字母在每个字符串中都出现多次的情况
此处可以另一种方法考虑,先设置一个数组1,里面存储第一个字符串里面各个字母出现的次数,再设置一个数组2,里面存储第二个字符串中字母出现的个数,然后将数组1与数组2进行比较,当某个元素在两个字符串中都出现时,取出现次数较小的数字,将其赋值给数组1,然后重置数组2,扫描第三个字符串。。。就是一个反复迭代的过程
代码如下
class Solution {
public List<String> commonChars(String[] A) {
int[] hash = new int[26];
boolean firstFlag = true;
for (String word : A) {
char[] wordChars = word.toCharArray();
if (firstFlag) {
for (char wordChar : wordChars) {
hash[wordChar - 97]++;
}
firstFlag = false;
}else {
int[] tmpHash = new int[26];
for (char wordChar : wordChars) {
tmpHash[wordChar - 97]++;
}
for(int i = 0; i < hash.length; ++i) {
if(hash[i] > tmpHash[i]) {
hash[i] = tmpHash[i];
}
}
}
} /
List<String> res = new ArrayList<>();
for(int i = 0; i < hash.length; ++i) {
if(hash[i] != 0) {
String tmp = String.valueOf((char)(i + 97));
for(int j = 0; j < hash[i]; ++j) {
res.add(tmp);
}
}
}
return res;
}
}