力扣01:两数之和

115 阅读1分钟

题目描述:

这是力扣上的第一道题: 两数之和

image.png image.png

我们先来提取一些信息:

  1. 数组无序
  2. 取值范围存在负数
  3. 返回下标
  4. 只会存在一个正确答案
  5. 存在重复元素
  6. 可以按照任意顺序返回

内容分析:

信息详细解读如下:

  • 由于题目要求返回的是【下标】, 所以不能使用【排序+双指针】方式,因为会破坏索引

    ⚠️:sort排序会改变原始数组

    如果采用排序方式,要记录原始的索引映射,但是js中的object对象,以及map都不允许key重复,[3,3]这种情况就无法正确映射

    如果采用复制一个新的数组,将新数组排序,从旧数组中获取对应索引,indexOf只会获取匹配到的第一个索引,[3,3]这种情况就会匹配成[0,0]

  • 所以这里我们采用暴力枚举/哈希表方式

解题方式:

基础版:暴力枚举

  • 时间复杂度:o(n2)
  • 空间复杂度:O(1)
var twoSum = function(nums, target) {
    for(let i = 0; i < nums.length-1; i++){
        for(let j = i+1; j < nums.length; j++){
            if(nums[i]+ nums[j] == target){
                return [i,j]
            }
        }
    }
};

一般你看到这里就可以了,但因题目要求,希望可以进阶一下,优化一下复杂度

进阶版:哈希表

小巧思:另一个元素 = 目标元素 - 当前遍历到的元素(即target-nums[i])

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
var twoSum = function(nums, target) {
   // 进阶版 
   let map = new Map([[nums[0],0]]);
   for(let i=1; i<nums.length; i++){
       let another = target - nums[i];
       if(map.has(another)){
           return [i,map.get(another)]
       }
       map.set(nums[i],i)
   }
};

小作业:

输入有序数组的两数之和