如何查找数组中第二个出现索引最小的首个重复数?代码调试求助
解决数组中找第二次出现位置最早的重复元素问题
首先,先帮你梳理下你的代码里存在的几个关键问题:
- 函数参数
array完全没用到,反而硬编码了一个固定数组a,导致传入的测试用例根本不会被处理; - 内层循环的
break位置错误,直接放在if语句外面,导致内层循环只执行一次(仅检查i+1位置的元素),根本没遍历后续元素找重复; - 你把
firstDuplicate赋值为元素第一次出现的索引,而题目要求返回的是重复元素本身,不是索引; - 没有处理无重复元素的情况,默认返回空字符串,不符合预期的
-1。
接下来明确问题需求:给定元素取值为1到数组长度的数组,找到第二次出现位置最早的重复元素;如果没有重复元素,返回-1。比如测试用例[2,1,3,5,3,2]中,3的第二次出现位置是4,2的第二次出现位置是5,所以3是答案。
解法思路
我们可以用哈希表(JavaScript中的Map)记录每个元素第一次出现的索引,然后遍历数组:
- 遍历数组的每个元素,记录当前索引;
- 如果元素已在哈希表中,说明这是它第二次出现,比较当前索引是否是目前最小的第二次出现索引,更新对应的结果元素;
- 如果元素不在哈希表中,就把它和第一次出现的索引存入哈希表;
- 遍历结束后,若找到符合条件的元素则返回,否则返回
-1。
另外,因为题目说明元素取值是1到数组长度,我们还可以用数组本身作为标记空间,把空间复杂度降到O(1):
- 对于每个元素
num,取它对应的索引num - 1(元素从1开始,数组索引从0开始); - 如果该索引位置的元素已是负数,说明
num之前出现过,这就是一个候选重复元素; - 如果是正数,就把该位置的元素转为负数,标记为已出现过;
- 同样,我们需要记录第二次出现位置最早的那个元素。
修正后的代码(哈希表版本,易理解)
function findSecondEarliestDuplicate(array) { const firstOccurrence = new Map(); let minSecondIndex = Infinity; let result = -1; for (let i = 0; i < array.length; i++) { const num = array[i]; if (firstOccurrence.has(num)) { // 这是第二次出现,比较当前索引是否更小 if (i < minSecondIndex) { minSecondIndex = i; result = num; } } else { firstOccurrence.set(num, i); } } return result; }
测试用例验证
- 测试输入
[2,1,3,5,3,2]:遍历到索引4时,3已在Map中,此时i=4小于Infinity,所以result=3;后续遍历到索引5时,2的第二次出现索引5大于4,结果保持3,符合预期。 - 测试输入
[2,4,3,5,1]:无重复元素,返回-1,符合预期。 - 测试输入
[2,4,3,5,1,7]:无重复元素,返回-1。
优化版(O(1)空间复杂度)
利用数组元素的取值范围,我们可以原地标记(注意:该版本会修改原数组,若不想修改可先复制一份数组再操作):
function findSecondEarliestDuplicate(array) { let minSecondIndex = Infinity; let result = -1; for (let i = 0; i < array.length; i++) { const num = Math.abs(array[i]); const index = num - 1; if (array[index] < 0) { // 该元素之前出现过,记录第二次出现的索引 if (i < minSecondIndex) { minSecondIndex = i; result = num; } } else { // 标记为已出现 array[index] = -array[index]; } } return result; }
内容的提问来源于stack exchange,提问作者LAnga
相关产品推荐
相关产品推荐

