两数之和算法问题咨询:如何返回数组中和为目标值的两数下标
问题分析
你现有代码存在两个核心问题导致无法获取原数组下标:
- 使用
Set存储提取的数值会自动去重,如果原数组存在重复值(比如输入为[{key1:3},{key1:3}],目标值为6),去重后仅保留一个数值,根本无法匹配到两个符合条件的元素 - 提取数值时直接丢弃了和原数组下标的绑定关系,就算找到符合条件的数值,也无法回溯对应的原始下标
最优实现方案(O(n)时间复杂度)
推荐用Map存储已遍历数值和对应下标的映射,一次遍历即可得到结果,性能远高于双重循环:
const arr = [{key1: 2}, {key1: 7}, {key1: 11}, {key1: 15}]; const target = 9; // 存储 数值: 原数组下标 的映射 const numIndexMap = new Map(); for (let i = 0; i < arr.length; i++) { // 提取当前元素的数值,如果你需要适配不同的key,可以替换为 Object.values(arr[i])[0] const currentVal = arr[i].key1; // 计算当前值需要匹配的差值 const diff = target - currentVal; // 差值已存在,直接返回两个下标 if (numIndexMap.has(diff)) { // 这里return即可得到结果,示例直接打印 console.log([numIndexMap.get(diff), i]); // 输出 [0, 1] break; } // 差值不存在,将当前值和下标存入Map numIndexMap.set(currentVal, i); }
原有双重循环逻辑的修改方案
如果你坚持要用双重循环的写法,可以直接遍历原数组,不要提前提取数值到Set丢失下标:
const arr = [{key1: 2}, {key1: 7}, {key1: 11}, {key1: 15}]; const target = 9; let result = []; for (let i = 0; i < arr.length; i++) { const val1 = arr[i].key1; for (let j = i + 1; j < arr.length; j++) { const val2 = arr[j].key1; if (val1 + val2 === target) { result = [i, j]; break; } } if (result.length) break; } console.log(result); // 输出 [0, 1]
注意事项
- 如果题目要求返回所有符合条件的下标对,将匹配到的下标对push到结果数组即可,不需要break
- 如果数组元素的key不固定,可以用
Object.values(arr[i])[0]替换代码中写死的key1取值逻辑 - Map方案时间复杂度为O(n)、空间复杂度为O(n),远优于双重循环的O(n²)时间复杂度,更适合处理大规模数组
内容的提问来源于stack exchange,提问作者Carolyn Cordeiro
相关产品推荐
相关产品推荐

