js - 两数之和并返回各自下标

1,384 阅读2分钟

egg

给定 nums = [2, 3, 5, 9], target = 7
 
因为 nums[0] + nums[3] = 2 + 5 = 7
所以返回 [0, 2]

暴力法

  • 双层for循环查找,可以联想9*9乘法表的实现
function twoSum(arr, target) {
let len = arr.length
    for (let i = 0; i < len; i++) {
        for (let j = 0; j < len; j++) {
            if (arr[i] + arr[j] === target) {
                return [i, j]
            }
        }
    }
}
let arr = [2, 3, 5, 9]
console.log(twoSum(arr, 7)) // [0, 2]

查找表法

  • 在遍历的同时,记录一些信息,以省去一层循环,这是以空间换时间的想法
  • 需要记录已经遍历过的数值和他对应的下标,可以借助查找表来实现
  • 查找表常用的两个实现
    • 哈希表
    • 平衡二叉树搜索
function twoSum(arr, target) {
    var temp = []
    let len = arr.length
    for (let i = 0; i < len; i++) {
        let dif = target - arr[i]
        if (temp[dif] !== undefined) {
            return [temp[dif], i]
        }
        temp[arr[i]] = i
    }
};
let arr = [2, 3, 5, 9]
console.log(twoSum(arr, 7)) // [0, 2]
  • 通过 let dif = target - arr[i] 分别获取目标值当前遍历元素的差值,如果这个差值作为哈希表的索引,能访问到有效元素,那么就说明当前遍历的itemp[dif] ,就是要找的索引

[2, 3, 5, 9] 目标值是 7

  1. i = 0; dif = 7 - 2 = 5 此时temp[dif] = temp[5] = undefined ;

所以走 temp[arr[i]] = i; temp[2] = 0 // 哈希表存存储遍历过的数值和对应下标

  1. i = 1; dif = 7 - 3 = 4 此时 temp[dif] = temp[4] = undefined ;

所以走 temp[arr[i]] = i; temp[3] = 1 // 哈希表存存储遍历过的数值和对应下标

  1. i = 2; dif = 7 - 5 = 2 此时 temp[dif] = temp[2] = 0 ;

此时这个差值作为哈希表的索引,能访问到有效元素,那么就说明当前遍历的itemp[dif] ,就是要找的索引 , 所以return [temp[dif], i] 所以 最后结果是[0, 2]

哈希表最优解

function twoSum(arr, target) {
  let map = new Map(); 
  for (let i = 0; i < arr.length; i++) {
    let subResult = target - arr[i];
    if (map.has(subResult)) {
      return [map.get(subResult), i];
    }
    map.set(arr[i], i);
  }
  return [];
}
console.log(twoSum(arr, 9));

哈希表阅读: 哈希表阅读

平衡二叉树搜索: 平衡二叉树搜索