目标
给你一个 环形 数组 nums 和一个数组 queries 。
对于每个查询 i ,你需要找到以下内容:
- 数组 nums 中下标 queries[i] 处的元素与 任意 其他下标 j(满足 nums[j] == nums[queries[i]])之间的 最小 距离。如果不存在这样的下标 j,则该查询的结果为 -1 。
返回一个数组 answer,其大小与 queries 相同,其中 answer[i] 表示查询i的结果。
示例 1:
输入: nums = [1,3,1,4,1,3,2], queries = [0,3,5]
输出: [2,-1,3]
解释:
查询 0:下标 queries[0] = 0 处的元素为 nums[0] = 1 。最近的相同值下标为 2,距离为 2。
查询 1:下标 queries[1] = 3 处的元素为 nums[3] = 4 。不存在其他包含值 4 的下标,因此结果为 -1。
查询 2:下标 queries[2] = 5 处的元素为 nums[5] = 3 。最近的相同值下标为 1,距离为 3(沿着循环路径:5 -> 6 -> 0 -> 1)。
示例 2:
输入: nums = [1,2,3,4], queries = [0,1,2,3]
输出: [-1,-1,-1,-1]
解释:
数组 nums 中的每个值都是唯一的,因此没有下标与查询的元素值相同。所有查询的结果均为 -1。
说明:
- 1 <= queries.length <= nums.length <= 10^5
- 1 <= nums[i] <= 10^6
- 0 <= queries[i] < nums.length
思路
有一个环形数组 nums 和一个查询数组 queries,返回 元素值与 queries[i] 相同的其它元素之间的最小距离,如果不存在则结果为 -1,返回查询结果数组。
根据元素值分组,分组内记录下标。针对每个查询,二分查找元素在分组中的位置,比较前后下标的距离,如果分组只有一个元素,返回 -1。需要特殊处理首与尾的最近距离。
也可以分组后预处理每个位置的最近距离,统一计算前后的最近距离,查询时直接取结果即可。注意循环数组的距离处理,这里直接将超出的距离映射回了原数组下标,因此最近距离需要取 min(d, n - d),其中 d = abs(i - j) 表示下标 i 与 j 的距离。
代码
/**
* @date 2026-04-16 8:55
*/
public class SolveQueries3488 {
public List<Integer> solveQueries_v1(int[] nums, int[] queries) {
Map<Integer, List<Integer>> map = new HashMap<>();
int n = nums.length;
for (int i = 0; i < n; i++) {
map.putIfAbsent(nums[i], new ArrayList<>());
map.get(nums[i]).add(i);
}
int[] dis = new int[n];
for (List<Integer> list : map.values()) {
int size = list.size();
for (int i = 0; i < size; i++) {
int index = list.get(i);
if (size >= 2) {
int prev = Math.abs(index - list.get((size + i - 1) % size));
int next = Math.abs(list.get((i + 1) % size) - index);
dis[index] = Math.min(Math.min(prev, n - prev), Math.min(next, n - next));
} else {
dis[index] = -1;
}
}
}
List<Integer> res = new ArrayList<>(queries.length);
for (int query : queries) {
res.add(dis[query]);
}
return res;
}
}
性能











