华为OD机试真题——阿里巴巴找黄金宝箱(III)(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
2025 A卷 100分 题型
本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享》
华为OD机试真题《阿里巴巴找黄金宝箱(III)》:
文章快捷目录
题目描述及说明
Java
python
JavaScript
C
GO
题目名称:阿里巴巴找黄金宝箱(III)
- 知识点:哈希表、滑动窗口、逻辑分析
- 时间限制:1秒
- 空间限制:256MB
- 限定语言:不限
题目描述
一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,每个箱子上面贴有一个数字。
阿里巴巴念出一个咒语数字,查看宝箱是否存在两个不同箱子,这两个箱子上贴的数字相同,同时这两个箱子的编号之差的绝对值小于等于咒语数字。
如果存在这样的一对宝箱,请返回最先找到的那对宝箱左边箱子的编号,如果不存在则返回-1。
输入描述
- 第一行输入一个数字字串,数字之间使用逗号分隔,例如:
1,2,3,1
。- 1 ≤ 字串中数字个数 ≤ 100000
- -100000 ≤ 每个数字值 ≤ 100000
- 第二行输入咒语数字,例如:
3
。- 1 ≤ 咒语数字 ≤ 100000
输出描述
存在符合条件的箱子对时,返回左边箱子的编号;否则返回-1。
示例
输入1:
6,3,1,6
3
输出1:
0
说明:数字6
在索引0
和3
出现,差值绝对值为3,等于咒语数字3。
输入2:
5,6,7,5,6,7
2
输出2:
-1
说明:无满足条件的箱子对。
Java
问题分析
我们需要找到数组中是否存在两个不同索引的箱子,其数字相同且索引差的绝对值不超过给定咒语数字k。如果存在多个这样的对,返回最先出现的那对的左边箱子索引,否则返回-1。
解题思路
- 哈希表记录索引:使用哈希表存储每个数字出现的所有索引(按升序)。
- 滑动窗口检查:对于每个元素,检查其之前出现的索引,使用二分查找找到满足条件的最小索引。
- 高效查找:利用二分查找快速确定是否存在满足条件的索引,确保时间复杂度为O(n log n)。
代码实现
import java.util.*;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String[] numsStr = scanner.nextLine().split(",");int k = scanner.nextInt();int[] nums = new int[numsStr.length];for (int i = 0; i < numsStr.length; i++) {nums[i] = Integer.parseInt(numsStr[i]);}Map<Integer, List<Integer>> numIndices = new HashMap<>();int result = -1;for (int i = 0; i < nums.length; i++) {int num = nums[i];if (numIndices.containsKey(num)) {List<Integer> indices = numIndices.get(num);int m = i - k;int target = i - 1;// 二分查找第一个 >= m 的索引int index = Collections.binarySearch(indices, m);if (index < 0) {index = -index - 1;}if (index < indices.size()) {int j = indices.get(index);if (j <= target) {result = j;break;}}}// 添加当前索引到哈希表,保持列表有序numIndices.computeIfAbsent(num, key -> new ArrayList<>()).add(i);if (result != -1) {break;}}System.out.println(result);}
}
代码详解
-
输入处理:
- 读取输入字符串并分割为数组,将每个元素转为整数。
- 读取咒语数字k。
-
哈希表初始化:
numIndices
存储每个数字对应的索引列表,确保列表升序。
-
遍历数组:
- 对每个元素
num
检查其是否在哈希表中存在。 - 若存在,获取对应的索引列表,计算
m = i - k
和target = i - 1
。
- 对每个元素
-
二分查找:
- 使用
Collections.binarySearch
找到第一个大于等于m
的索引位置。 - 若找到且该索引对应的值不超过
target
,返回该索引作为结果。
- 使用
-
添加当前索引:
- 将当前元素的索引加入哈希表对应的列表中,保持列表有序。
-
输出结果:
- 若找到符合条件的索引,立即输出并结束循环;否则最终输出-1。
示例测试
示例1:
输入:
6,3,1,6
3
输出:
0
解析:索引3的数字6,检查到索引0的6满足3-0=3 <=3,返回0。
示例2:
输入:
5,6,7,5,6,7
2
输出:
-1
解析:所有相同数字的索引差均超过2,返回-1。
示例3:
输入:
0,0
1
输出:
0
解析:索引0和1的差1 <=1,返回0。
综合分析
- 时间复杂度:O(n log n),每个元素的二分查找时间为O(log n)。
- 空间复杂度:O(n),存储每个数字的索引列表。
- 最优性:利用哈希表和二分查找高效定位,避免暴力枚举,适用于大数据量。
- 适用场景:处理大规模数据时仍保持高效