咨询Codefights代码逻辑:寻找数组中二次出现索引最小的首个重复数
解析Codefights重复数字问题的代码逻辑
嘿,咱们来一步步拆解这道题的核心需求和典型解法代码的执行逻辑吧!
首先明确题目要求:给定一个元素值范围在1到数组长度之间的数组a,要找出第二次出现的索引最小的重复数字。如果有多个重复数字,谁的第二次出现位置更早,就返回谁;要是数组里没有重复元素,就返回-1(这是这类题的常规默认结果)。
我先贴出这道题的典型解法代码(Python版本),再逐段解析:
def firstDuplicate(a): seen = {} min_second_idx = float('inf') result = -1 for idx, num in enumerate(a): if num in seen: # 当前数字是第二次出现 if idx < min_second_idx: min_second_idx = idx result = num else: seen[num] = idx return result
代码执行全流程拆解
初始化环节:
seen:一个字典,专门用来记录每个数字第一次出现的索引,方便后续判断是否重复。min_second_idx:初始设为无穷大,用来跟踪目前找到的所有重复数字中,第二次出现的最小索引。result:初始值为-1,代表默认没有重复元素的情况。
遍历数组环节:
- 用
enumerate遍历数组,同时拿到当前元素的索引idx和数值num,这样我们既能知道数字是什么,也能知道它的位置。 - 如果
num已经在seen字典里:- 说明这是这个数字第二次出现了!此时我们对比当前索引
idx和min_second_idx:- 如果
idx更小,说明这个数字的第二次出现位置比之前记录的更早,那我们就更新min_second_idx为当前索引,同时把result改成这个数字。
- 如果
- 说明这是这个数字第二次出现了!此时我们对比当前索引
- 如果
num不在seen里:- 那就把这个数字和它的第一次出现索引存入
seen字典,方便后续遇到重复时判断。
- 那就把这个数字和它的第一次出现索引存入
- 用
返回结果环节:
- 遍历完整个数组后,
result要么是符合要求的重复数字,要么是-1(数组无重复时)。
- 遍历完整个数组后,
关键逻辑细节说明
- 为什么只记录第一次出现的索引?因为我们只关心数字第二次出现的位置,第一次出现的位置仅用来判断是否是重复,后续不需要更新——毕竟题目要的是第二次出现最早的数字,更早的第二次出现才是我们的目标。
- 为什么每次遇到重复就立刻比较更新?因为数组是按顺序遍历的,一旦遇到更早的第二次出现位置,我们就需要及时更新结果,这样遍历结束时就能直接得到正确答案,不需要额外再遍历一次统计结果。
- 题目里提到元素范围是1到
a.length,其实这是个小提示:我们可以用数组代替字典来记录(比如创建长度为a.length+1的数组,用数字本身作为下标),但字典的写法更通用,逻辑完全一致。
举个实际例子帮你理解:比如数组是[2, 1, 3, 1, 4, 2],遍历过程如下:
- 数字2不在
seen里,存入seen[2] = 0 - 数字1不在
seen里,存入seen[1] = 1 - 数字3不在
seen里,存入seen[3] = 2 - 数字1在
seen里,当前索引是3,比初始的无穷大小,所以更新min_second_idx=3,result=1 - 数字4不在
seen里,存入seen[4] =4 - 数字2在
seen里,当前索引是5,比3大,所以不更新结果
最后返回1,完全符合题目要求——因为1的第二次出现索引3比2的第二次出现索引5更早。
内容的提问来源于stack exchange,提问作者skypen
相关产品推荐
相关产品推荐

