LeetCode-两数之和

本文探讨了一种高效的解题方法,利用哈希表数据结构避免了双重循环,解决了在给定整数数组中找到和为目标值的两个数的问题。讲解了从初解到高手解法的转变,以及哈希表在解决此类问题中的关键作用和应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例:

给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]

初解题:

  1. 数组中数字不可以重复使用
  2. 返回一个数组
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
    let result = []
    nums.map((first,i) => {
        let secondIndex = i + 1
        let second = nums[secondIndex]
        let sum = first + second
        if(sum === target) {
            result.push(i,secondIndex)
        }
    })
    return result
};

结论:通过了示例测试,但未未考虑到当数组为 [3,2,3],target = 6的情况

思考后修改如下:

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
    let result = []
    nums.map((first,i) => {
        let secondIndex = i + 1
        nums.forEach((second,j) => {
            let sum = first + second
            if(j >= secondIndex && sum === target) {
                result.push(i,j)
            }

        });
    })
    return result
};


高手解法:

高手:@tboys

解题思路

哈希表

  1. 遍历的同时,记录一些信息,省去一层循环,[以空间换时间]
  2. 需要记录已经遍历过的数值和它对应的下标,借助查表实现

实现思路

遍历到数字 a 时,用 targettarget 减去 a,就会得到 b,若 b 存在于哈希表中,我们就可以直接返回结果了。若 b 不存在,那么我们需要将 aa 存入哈希表,好让后续遍历的数字使用。

大佬有动画图解,一看就懂。@demigodliu

知识点:

哈希表也被称为散列表,Hash表是一种特殊的数据结构,它同数组、栈、链表等相比较有很明显的区别,它能够快速定位到想要查找的记录,而不是与表中存在的记录的关键字进行比较来进行查找。

哈希表是基于键值对的一种数据存储结构,key值不可以重复,value可以重复,后面添加的重复的key值的时候,会把之前key值对应的value给覆盖掉,JavaScript中的对象具有天然的哈希特性。

Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值。

相比较Object而言,Map的性能在频繁增删键值对的场景下表现更好

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
    let len = nums.length;
    // 创建 MAP
    const MAP = new Map();
    /**
    *Map.prototype.set(key, value)
		*设置Map对象中键的值。返回该Map对象。
    */ 
    // 由于第一个元素在它之前一定没有元素与之匹配,所以先存入哈希表
    MAP.set(nums[0], 0);
    for (let i = 1; i < len; i++) {
        // 提取共用
        let other = target - nums[i];
        // 判断是否符合条件,返回对应的下标
        if (MAP.get(other) !== undefined) return [MAP.get(other), i];
        // 不符合的存入hash表
        MAP.set(nums[i], i)
    }
};

JavaScript中的对象具有天然的哈希特性

来源:@xiao_ben_zhu

const twoSum = (nums, target) => {
  const prevNums = {};                    // 存储出现过的数字,和对应的索引               

  for (let i = 0; i < nums.length; i++) {       // 遍历元素   
    const curNum = nums[i];                     // 当前元素   
    const targetNum = target - curNum;          // 满足要求的目标元素   
    const targetNumIndex = prevNums[targetNum]; // 在prevNums中获取目标元素的索引
    if (targetNumIndex !== undefined) {         // 如果存在,直接返回 [目标元素的索引,当前索引]
      return [targetNumIndex, i];
    } else {                                    // 如果不存在,说明之前没出现过目标元素
      prevNums[curNum] = i;                     // 存入当前的元素和对应的索引
    }
  }
}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值