
本文介绍如何准确找出字符串数组中在每个字符串里至少出现一次的公共字符,并统计其在整个数组中的总出现次数(非每字符串内频次之和),避免重复计数导致错误结果。
本文介绍如何准确找出字符串数组中在每个字符串里至少出现一次的公共字符,并统计其在整个数组中的总出现次数(非每字符串内频次之和),避免重复计数导致错误结果。
要解决“找出字符串数组中在所有索引(即每个字符串)中均存在的字符,并统计其全局总频次”这一问题,关键在于:每个字符串对某字符的贡献最多为 1 次——即使该字符在某个字符串中重复出现(如 "been" 中 'e' 出现两次),它也只代表该字符串“含有 'e'”,不能因此累加多次。
原代码的错误根源在于:它对每个字符在每个字符串中的每次出现都进行了计数(例如 'e' 在 "been" 中被加了 2 次),导致 repeated_char.get('e') 最终为 4("been"×2 + "bean"×1 + "bread"×1 = 4),误判为满足 >= str.length(即 ≥4)条件,从而错误输出 'e':4。
✅ 正确思路是:
- 遍历每个字符串;
- 对当前字符串,用一个
HashSet<character></character>记录已处理过的字符(去重); - 仅当该字符首次在当前字符串中出现时,才更新全局计数器;
- 最终,只有计数值等于字符串数组长度的字符,才说明它在每个字符串中至少出现了一次。
以下是修正后的完整实现:
import java.util.*;
public class RepeatedChar {
public static Map<Character, Integer> repeatedChars(String[] str) {
if (str == null || str.length == 0) {
return new HashMap<>();
}
Map<Character, Integer> globalCount = new HashMap<>();
for (String s : str) {
if (s == null) continue;
Set<Character> seenInCurrent = new HashSet<>(); // 当前字符串已见字符
for (char c : s.toCharArray()) {
if (!seenInCurrent.contains(c)) {
globalCount.put(c, globalCount.getOrDefault(c, 0) + 1);
seenInCurrent.add(c);
}
}
}
// 筛选出在所有字符串中均出现的字符(count == str.length)
Map<Character, Integer> result = new HashMap<>();
for (Map.Entry<Character, Integer> entry : globalCount.entrySet()) {
if (entry.getValue() == str.length) {
result.put(entry.getKey(), entry.getValue());
}
}
return result;
}
public static void main(String[] args) {
String[] input = {"been", "bean", "bread", "boat"};
System.out.println(repeatedChar(input)); // 输出: {b=4}
}
}? 注意事项:
- 本解法统计的是「跨字符串的覆盖频次」,即
result.get('b') == 4表示'b'在全部 4 个字符串中均存在(各贡献 1 次),而非'b'总共出现了 4 次; - 若需同时获取「全局总出现次数」(如
'b'实际共出现 4 次、'e'共出现 6 次),应额外维护一个独立的totalOccurrence计数器,与globalCount分开计算; - 输入含
null字符串或空字符串时,代码已做防御性处理,确保健壮性。
该方案时间复杂度为 O(N×M),其中 N 是数组长度,M 是字符串平均长度;空间复杂度为 O(K),K 为所有字符串中不同字符总数。简洁、高效且语义清晰,适用于通用多字符串公共字符分析场景。

















