数组首重复值编码挑战:描述有误还是我的解法出错?
分析你的问题:第一个重复元素的第二次出现位置
首先,先明确你的题目要求:找到第二个出现位置索引最小的首个重复数字——这个表述有点绕,我们拆解一下核心需求:
- 我们需要在数组中找出所有存在重复的元素
- 对于每个重复元素,找到它第二次出现的索引
- 在这些索引中,找到最小的那个,然后返回这个索引的1-based位置(因为你的代码返回的是
Math.min(...) +1)
针对输入[3,3,3],你的代码逻辑是完全正确的:
- 第一个3(索引0)的第二次出现位置是索引1
- 第二个3(索引1)的第二次出现位置是索引2
- 过滤后得到的重复位置数组是
[1,2],取最小值1,加1后得到2,这和你的输出一致
那为什么你会疑惑呢?可能是题目描述的表述存在歧义。如果题目实际要求是返回第一个重复出现的数字本身(比如对于[3,3,3]返回3),那你的代码就不符合要求,但根据你给出的题目描述“找到第二个出现位置索引最小的首个重复数字”,更合理的理解是返回那个最早的第二次出现的位置(1-based就是2),所以你的解法是正确的。
额外的优化建议
你的代码逻辑是对的,但效率上有可以优化的地方:indexOf会每次遍历数组,对于大数组来说时间复杂度是O(n²)。可以用哈希表来记录每个元素第一次出现的索引,然后遍历数组时检查是否已经存在,这样时间复杂度可以降到O(n):
function firstDuplicate(a) { const seen = new Map(); for (let idx = 0; idx < a.length; idx++) { const el = a[idx]; if (seen.has(el)) { // 返回第二次出现的1-based位置 return idx + 1; } else { seen.set(el, idx); } } return -1; }
这个版本对于[3,3,3]同样会返回2,而且效率更高,同时逻辑更清晰——一旦找到第一个重复的元素(也就是第二次出现的位置最早的那个),直接返回结果,不需要遍历整个数组。
总结
针对你给出的题目描述,你的代码在[3,3,3]的输出是完全正确的。如果题目实际要求和你理解的不同(比如返回重复的数字本身),那才需要调整解法,但根据当前信息,你的答案没问题。
内容的提问来源于stack exchange,提问作者Tyler L
相关产品推荐
相关产品推荐

