题目
给定仅有小写字母组成的字符串数组 A,返回列表中的每个字符串中都显示的全部字符(包括重复字符)组成的列表。例如,如果一个字符在每个字符串中出现 3 次,但不是 4 次,则需要在最终答案中包含该字符 3 次。
你可以按任意顺序返回答案。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/find-common-characters 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的代码
很惭愧,这道题以我目前对java的了解程度没能做出来。我能够想到的方法非常非常负责,我认为一定不能这么干,于是去看了题解,发现题解使用了Map。然而我对Map近乎一无所知,于是简单学习了一下Map学习笔记 下面还是看被人的代码吧。
别人的代码
class Solution {
public List
<String> commonChars(String
[] A
) {
List
<String> result
= new ArrayList<>();
if(A
== null
|| A
.length
< 2){
return result
;
}
List
<Map
<Character, Integer>> list
= new ArrayList<>();
for (String a
: A
) {
Map
<Character, Integer> map
= new HashMap<>();
for (char c
: a
.toCharArray()) {
if (map
.containsKey(c
)) {
map
.put(c
, map
.get(c
) + 1);
} else {
map
.put(c
, 1);
}
}
list
.add(map
);
}
Set
<Character> retainSet
= list
.get(0).keySet();
for (int i
= 1; i
< list
.size(); i
++) {
retainSet
.retainAll(list
.get(i
).keySet());
}
Iterator
<Character> iterator
= retainSet
.iterator();
while (iterator
.hasNext()){
Character current
= iterator
.next();
int minCount
= list
.get(0).get(current
);
for (int i
= 1; i
< list
.size(); i
++) {
Integer cnt
= list
.get(i
).get(current
);
if(cnt
< minCount
){
minCount
= cnt
;
}
}
作者:ge
-bi
-xiao
-wang
链接:https
://leetcode
-cn
.com
/problems
/two
-sum
/solution
/zi
-fu
-tong
-ji
-fa
-by
-ge
-bi
-xiao
-wang
/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
小结
代码首先提醒了我,java遍历数组完全可以用String a:A,这种写法用List存储不确定长度的结果用Map进行技术(相当于使用Hash定位存储位置用Set找到共有的字符用交集中字符的最小出现次数作为重复部分
但是提交后时间复杂度表现非常差,还是看看官方快速解题的代码
官方更优解
class Solution {
public List
<String> commonChars(String
[] A
) {
if(A
== null
|| A
.length
== 0 || A
.length
== 1) {
return null
;
}
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
;
}
}
入参检查!!!!!很关键!!!!!要鲁棒!!!!最优解的思路,即转换成ASCII来用int值做键,这一点我是想到了,但是计数的时候我的思路出现了混乱。因为最开始我是准备所有的字符串都用同一个int数组,然后不断累积出现次数,这样我就发现,假设输入为3个字符串,重复字符a出现的次数分别为3,2,1,则按照我的方法会输出2,但其实应该输出1。于是我的思路到此截止。于是我的思路的郁结点在于,没有意识到,对于求最小公共部分,始终保留最小的那个数就可以了。