Given an array A of strings made only from lowercase letters, return a list of all characters that show up in all strings within the list (including duplicates). For example, if a character occurs 3 times in all strings but not 4 times, you need to include that character three times in the final answer.
You may return the answer in any order.
这道题LeetCode显示的是easy,但是我想了大概一个小时,最终放弃了,看了别人的答案。。。
看了一个博主,谈到了申请了一个代表26个字母的int数组,我也想到了,但是无法想象如果有100个这样的数组,如何比较呢???
结果博主每一个字符串数组中同样申请一个临时的26个字母的int数组,然后遍历给定的字符串数组,在对这个字符串的每一个字母遍历后,拿新申请的数组与开始申请的数组对应元素(相同下标)进行比较,如果哪个数字小就用谁!!! 这样子每次只用比较两个int数组,没有我想象的最多100个数组同时比较的情况,这个脑回路我怎么没有额。。。
**
附上博主的链接:LeetCode126周赛-1002. 查找常用字符-Java实现
**
搞懂了博主的思路后,我自己打了一遍代码,后来发现了自己的两个薄弱点:
1、Foreach语句
题目要对数组赋初值,应该只能用for循环语句,如下:
for(int i = 0;i < 26;i++){
chars[i] = Integer.MAX_VALUE;
}
但是,我为了让代码简洁,竟然自作聪明的用了Foreach语句,如下:
for(int i:chars) {
i = Integer.MAX_VALUE;
}
其实,看了Foreach语句的介绍,我就明白我错了
for(int x : f) //定义一个int类型的变量x,继而将每一个f的元素赋值给x
2、算法简洁性
记录content字符数组中的每个字母的出现次数,通过charsTemp数组记录(该数组0-25依次代表a-z)
我的思路:
for(int j = 0; j < content.length ; j++) { //取出每个字母
for(int k = 97 ; k<= 122 ; k++) { //依次与a-z做对比,如果相同,contentChars数组中对应字母位置+1
char c = (char)k;
if(c == content[j]) {
charsTemp[k-97]++;
break;
}
}
}
博主的思路:
for(char c : content){
charsTemp[c-97]++;
}
在讨论中看到了另外一种解法:HashMap
public List<String> commonChars(String[] A) {
// List to store results
List<String> result = new ArrayList<String>();
//跟踪每个单词的字母数的计数器
Map<Character, Integer> counter = null;
//hashmap保持所有单词中每个字母的最小计数
Map<Character, Integer> min = new HashMap<Character, Integer>();
//因为字母都是小写的,所以循环使用最小哈希映射26次(a-z),字符作为键,Integer.MAX_VALUE作为值。
for(int i = 0; i < 26; i++) {
char ch = (char) ('a' + i);
min.put(ch, Integer.MAX_VALUE);
}
// 遍历每个单词
for(String word : A) {
// 为每个单词创建HashMap
counter = new HashMap<Character, Integer>();
// 查找当前字符串中的字符数
for(char ch : word.toCharArray()) {
counter.put(ch, counter.getOrDefault(ch, 0) + 1);
//getOrDefault()方法:当HashMap集合中有这个key时,就使用这个key值,如果没有就使用默认值defaultValue
}
/*
遍历所有26个字符。这个循环背后的思想是,对于[a-z]中的每个字符,
我们将找到全局最小值(该字符的)和本地字符计数的最小值,
并相应地更新最小值。所以如果一个字符不存在,新的最小值将变为零
*/
for(Map.Entry<Character, Integer> entry : min.entrySet()) {
char alphabet = entry.getKey();
int currentValue = counter.containsKey(alphabet) ? counter.get(alphabet) : 0;
int currentMinValue = entry.getValue();
min.put(alphabet, Math.min(currentMinValue, currentValue));
}
}
// 遍历Min HashMap并将字符添加到结果中
// depending on the occurrence
for(Map.Entry<Character, Integer> entry : min.entrySet()) {
int count = entry.getValue();
while(count-- > 0) {
result.add("" + entry.getKey());
}
}
return result;
}