题目:
给定仅有小写字母组成的字符串数组 A,返回列表中的每个字符串中都显示的全部字符(包括重复字符)组成的列表。例如,如果一个字符在每个字符串中出现 3 次,但不是 4 次,则需要在最终答案中包含该字符 3 次。
你可以按任意顺序返回答案。
来源:力扣(LeetCode)
解:
这道题暴力破解的话,时间复杂度达到O(n^3),不采取。
所谓重复数,即两种情况,重复的取最小重复次数,不重复的删除(字符重复指每个字符串都要出现)。
用数组标记法,这里用java的map标记。每一次字符串遍历,计算当前字符重复情况,跟之前存下的重复字符情况比较,重复的保存次数最小值,不重复的删除。时间复杂度o(n^2)。
import java.util.HashMap;
import java.lang.Math;
class Solution {
public List<String> commonChars(String[] A) {
List<String> ls=new ArrayList<String>();
if(A==null || A.length==0){
return ls;
}
//初始化
char[] ar=A[0].toCharArray();
HashMap<Character,Integer> hm=new HashMap<Character,Integer>(); //保存前字符串重复值
HashMap<Character,Integer> hmt=new HashMap<Character,Integer>(); //当前字符串计算临时存储map
for(char c : ar){
if(hm.containsKey(c)){
hm.put(c,hm.get(c)+1);
}else{
hm.put(c,1);
}
}
//遍历
for(int i=1;i<A.length;i++){
ar=A[i].toCharArray();
//计算当前字符串重复
for(char c : ar){
if(hmt.containsKey(c)){
hmt.put(c,hmt.get(c)+1);
}else{
hmt.put(c,1);
}
}
//比较之前重复字符
for(Iterator<Map.Entry<Character,Integer>> it=hm.entrySet().iterator();it.hasNext();){
Map.Entry<Character,Integer> et=it.next();
if(hmt.containsKey(et.getKey())){
hm.put(et.getKey(),Math.min(et.getValue(),hmt.get(et.getKey())));
}else{
it.remove();
}
}
//清空临时map--hmt--
for(Iterator<Map.Entry<Character,Integer>> it=hmt.entrySet().iterator();it.hasNext();){
it.next();
it.remove();
}
}
//结果返回
for(Map.Entry<Character,Integer> et : hm.entrySet()){
for(int i=et.getValue();i>0;i--){
ls.add(et.getKey().toString());
}
}
return ls;
}
}