2025 A卷 100分 题型
本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析;
并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式!
华为OD机试真题《找出两个整数数组中同时出现的整数》:
目录
题目名称:找出两个整数数组中同时出现的整数
属性 | 内容 |
---|---|
知识点 | 哈希表、计数统计、排序 |
时间限制 | 1秒 |
空间限制 | 256MB |
限定语言 | 不限 |
题目描述
给定两个整数数组(数组元素范围在[-1000,1000]
),找出所有在两个数组中同时出现的整数,并按升序排列返回。若同一数字在两个数组中出现的次数不同,则按较小次数输出(例如:数字3在数组A出现2次、数组B出现3次,则结果中输出两个3)。若不存在共同整数,返回空数组。
输入描述
两行输入:
第一行为数组A的数字,用逗号分隔,例如:1,2,3,1
第二行为数组B的数字,用逗号分隔,例如:1,1,2,4
输出描述
输出结果按升序排列,用逗号分隔。例如:1,1,2
(A和B中均包含1和2,其中1出现2次且取较小次数2,2出现1次)。若无交集,输出空字符串。
测试用例
- 输入:
1,2,3
1,1,2
输出:1,2
- 输入:
5,5,5
6
输出:
Java
问题分析
给定两个整数数组,找出所有在两个数组中同时出现的整数,并按升序排列返回。若同一数字在两个数组中出现次数不同,则按较小次数输出。若不存在共同整数,返回空数组。
解题思路
- 读取输入:将输入的字符串转换为两个整数数组。
- 统计次数:使用哈希表统计每个数字在两个数组中的出现次数。
- 求交集:找出两个哈希表中都存在的数字,并取出现次数的较小值。
- 生成结果:将每个数字按较小次数重复添加到结果列表。
- 排序输出:对结果列表升序排列,并转换为逗号分隔的字符串。
代码实现
import java.util.*;
public class Main {
public static void main(String[] args) {
// 1. 读取输入
Scanner scanner = new Scanner(System.in);
String lineA = scanner.nextLine();
String lineB = scanner.nextLine();
scanner.close();
// 2. 分割字符串并转换为整数数组
String[] partsA = lineA.split(",");
int[] arrayA = new int[partsA.length];
for (int i = 0; i < partsA.length; i++) {
arrayA[i] = Integer.parseInt(partsA[i]);
}
String[] partsB = lineB.split(",");
int[] arrayB = new int[partsB.length];
for (int i = 0; i < partsB.length; i++) {
arrayB[i] = Integer.parseInt(partsB[i]);
}
// 3. 统计数组A中各数字的出现次数
Map<Integer, Integer> countA = new HashMap<>();
for (int num : arrayA) {
countA.put(num, countA.getOrDefault(num, 0) + 1);
}
// 4. 统计数组B中各数字的出现次数
Map<Integer, Integer> countB = new HashMap<>();
for (int num : arrayB) {
countB.put(num, countB.getOrDefault(num, 0) + 1);
}
// 5. 遍历交集并生成结果列表
List<Integer> result = new ArrayList<>();
for (int num : countA.keySet()) {
if (countB.containsKey(num)) {
int minCount = Math.min(countA.get(num), countB.get(num));
for (int i = 0; i < minCount; i++) {
result.add(num);
}
}
}
// 6. 对结果列表排序
Collections.sort(result);
// 7. 格式化输出
StringBuilder output = new StringBuilder();
for (int i = 0; i < result.size(); i++) {
output.append(result.get(i));
if (i < result.size() - 1) {
output.append(",");
}
}
System.out.println(output);
}
}
代码详细解析
读取输入:
- 使用
Scanner
读取两行输入字符串。 split(",")
将字符串按逗号分割成字符串数组。- 转换为整数数组
arrayA
和arrayB
。
- 使用
统计次数:
HashMap
存储每个数字及其出现次数。countA.getOrDefault(num, 0) + 1
实现计数。
求交集:
- 遍历
countA
的键集合,检查是否存在于countB
。 - 若存在,取两次数的最小值,循环添加该数字到结果列表。
- 遍历
排序与输出:
Collections.sort(result)
对结果升序排列。StringBuilder
构建输出字符串,用逗号分隔元素。
测试示例
示例1:
- 输入:
1,2,3 1,1,2
- 输出:
1,2
- 解析:1在A中出现1次,B中出现2次 → 取1次;2均出现1次 → 取1次。
示例2:
- 输入:
5,5,5 6
- 输出:空字符串
- 解析:无共同数字。
综合分析
时间复杂度:
- 统计次数:O(n + m),遍历两个数组。
- 求交集:O(k),k为共同数字数量。
- 排序:O(r log r),r为结果元素总数。
- 总体时间复杂度为线性级别,适用于大数据量。
空间复杂度:
- 哈希表存储次数:O(n + m)。
- 结果列表:O®。
优势:
- 哈希表高效统计:快速查找和统计次数。
- 最小次数处理:直接比较并取较小值。
- 逻辑清晰:分步骤处理,易于理解和维护。
适用性:
- 支持负数和大范围整数。
- 处理大规模数据时性能稳定。
python
问题分析
我们需要找出两个整数数组中共同存在的所有整数,并按升序排列返回。如果同一个数字在两个数组中的出现次数不同,则按照较小的次数输出。例如,数组A中有3出现2次,数组B中有3出现3次,结果中需要输出两个3。如果没有共同数字,返回空数组。
输入输出示例:
- 输入:两行逗号分隔的整数。
- 输出:共同数字按升序排列的逗号分隔字符串,或空字符串。
解题思路
- 输入处理:将输入的字符串转换为整数列表。
- 统计次数:用哈希表统计每个数字在两个数组中的出现次数。
- 求交集:找到两个数组中共同存在的数字,并取较小的出现次数。
- 生成结果:按较小次数将数字重复添加到结果列表,并排序。
- 输出格式:将结果列表转换为逗号分隔的字符串。
代码实现
from collections import Counter
# 步骤1:读取输入并转换为整数列表
a = list(map(int, input().split(','))) # 输入示例:"1,2,3,1" → [1,2,3,1]
b = list(map(int, input().split(','))) # 输入示例:"1,1,2,4" → [1,1,2,4]
# 步骤2:统计每个数字的出现次数
count_a = Counter(a) # 示例结果:Counter({1: 2, 2: 1, 3: 1})
count_b = Counter(b) # 示例结果:Counter({1: 2, 2: 1, 4: 1})
# 步骤3:求交集,保留较小次数
common = count_a & count_b # 示例结果:Counter({1: 2, 2: 1})
# 步骤4:生成结果列表并按升序排列
result = sorted(common.elements()) # 示例结果:[1, 1, 2]
# 步骤5:格式化输出
print(','.join(map(str, result)) if result else '') # 示例输出:"1,1,2"
代码解析
读取输入
input().split(',')
:将输入字符串按逗号分割成字符串列表。- 例如,输入
"1,2,3,1"
会被转换为["1", "2", "3", "1"]
。
- 例如,输入
map(int, ...)