两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

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

方法一:暴力法 多层遍历
遍历每个元素num,并查找是否存在一个值与target - nun相等的目标元素。

var twoSum = function(nums, target) {
    for (let i = 0; i < nums.length; i++) {
      for (let j = i + 1; j < nums.length; j++) {
        if (nums[i] + nums[j] === target) {
          return [i, j]
        }
      }
    }
    return []
};
twoSum([2, 7, 11, 15], 9)

复杂度分析:

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
  • 空间复杂度: O ( 1 ) O(1) O(1)

方法二:数组遍历1
通过空间换取时间的方式。

var twoSum = function(nums, target) {
  let map = []
  for (let i = 0; i < nums.length; i++) {
    map.push(nums[i])
  }
  for (let i = 0; i < nums.length; i++) {
    const twice = target - map[i]
    const j = map.indexOf(twice)
    if (j > -1 && i !== j) {
      return [i, j]
    }
  }
  return []
};
twoSum([2, 7, 11, 15], 9)

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
    • 我们把包含有 n 个元素的列表遍历两次。由于数组将查找时间缩短到 O ( 1 ) O(1) O(1) ,所以时间复杂度为 O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)
    • 所需的额外空间取决于数组中存储的元素数量,该表中存储了 n n n 个元素。

方法三:数组遍历2
通过空间换取时间的方式。

var twoSum = function(nums, target) {
  let map = []
  for (let i = 0; i < nums.length; i++) {
    const twice = target - nums[i]
    const j = map.indexOf(twice)
    if (j > -1 && i !== j) {
      return [i, j]
    }
    map.push(nums[i])
  }
  return []
};
twoSum([2,7,11,15], 9)

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
    • 我们只遍历了包含有 n 个元素的列表一次。在表中进行的每次查找只花费 O ( 1 ) O(1) O(1) 的时间。
  • 空间复杂度: O ( n ) O(n) O(n)
    • 所需的额外空间取决于数组中存储的元素数量,该表最多需要存储 n n n 个元素。

方法四:双指针查找
(满足index必须小于index2,且不可重复使用相同的元素)
使用两个指针(low, high),初始位置分别为第一个元素和最后一个元素位置,比较两个元素之和sum与目标值target的大小,如果等于target值,则得到唯一解。如果比target值小,则将low的值加1;否则high加1。移动指针后重复上述操作直到找到答案或low等于high,跳出while循环。

var twoSum = function(numbers, target) {
  let low = 0
  let high = numbers.length - 1
  while(low < high) {
    const sum = numbers[low] + numbers[high] 
    if (sum === target) {
      return [low, high]
    } else if (sum > target) {
      high --
    } else {
      low ++
    }
  } 
};
twoSum([2, 7, 11, 15], 9)

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
    • 每个元素只被访问一次,总共n个元素。
  • 空间复杂度: O ( 1 ) O(1) O(1)
    • 只用到两个指针。

方法五:二分法查找
(满足index必须小于index2,且不可重复使用相同的元素)

const NOT_FOUND = -1
var twoSum = function(numbers, target) {
  for (let i = 0; i < numbers.length; i++) {
    let y = target - numbers[i]
    let res = binarySearch(numbers, y)
    if(res !== NOT_FOUND && i !== res){
      return i < res ? [i + 1, res + 1] : [res + 1, i + 1]
    }
  }
}
const binarySearch = function(array, target) {
  let low = 0
  let high = array.length - 1
  while (low <= high) {
    let mid = ~~((low + high) / 2)
    if (array[mid] < target) {
      low = mid + 1
    } else if (array[mid] > target) {
      high = mid - 1
    } else {
      return mid
    }
  }
  return NOT_FOUND
}
twoSum([2, 7, 11, 15], 9)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值