每日一题 01|算法题-两数之和

2020 年 12 月 12 日

阅读量:0

正文共 727 字,预计阅读时间 4 分钟

题目

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

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

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9

所以返回 [0, 1]

解法 1: 暴力枚举

利用双层 for 循环来解决这个问题,枚举出所有的可能性,这是最简单的思维方式。

Golang 解法

func twoSum(nums []int, target int) []int {
    for i := range nums {
        for j := range nums {
            if nums[i]+nums[j] == target && i != j {
                return []int{i, j}
            }
        }
    }
    return nil
}

JavaScript 解法

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function (nums, target) {
  for (let i = 0; i < nums.length; i++) {
    for (let j = 0; j < nums.length; j++) {
      if (nums[i] + nums[j] === target && i !== j) {
        return [i, j];
      }
    }
  }
  return [];
};

时间复杂度是 O(n2),n 是数组 nums 的长度。

空间复杂度是 O(1),只用到常数个临时变量。

这种问题一般的优化方案是以空间换时间。

解法 2: 查表法

可以分析得知,如果 target-nums[i] 的值在 nums 中同时存在,那么就可以得到第二个下标 j。这样可以在循环的过程中记录一些值,以省去一层 for 循环。

具体思路是在循环外设置一个 hash 表。当每次循环时,拿 target 减掉当前循环到的元素,得到的值如果在 hash 表中存在,就把 hash 表的值和当前循环的下标返回。每次循环结束时,将当前循环的值作为 hash 表的 key,当前循环的下标作为 hash 表的 value,存入 hash 表。

Golang 解法

func twoSum(nums []int, target int) []int {
    m := map[int]int{}
    for i, v := range nums {
        diff := target - v
        if j, ok := m[diff]; ok {
            if j != i {
                return []int{j, i}
            }
        }
        m[v] = i
    }
    return nil
}

JavaScript 解法

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function (nums, target) {
  var map = new Map();
  for (let i = 0; i < nums.length; i++) {
    let diff = target - nums[i];
    let j = map.get(diff);
    if (j !== void 0 && i != j) {
      return [j, i];
    }
    map.set(nums[i], i);
  }
  return [];
};

时间复杂度是 O(n),n 是数组 nums 的长度。

空间复杂度是 O(n),n 是 hash 表的长度,最短为 1,最长为 nums 的长度。

思考

这道题主要考察的是数组和哈希表的区别,以及以空间换时间的思路。

但在实际场景中还需要考虑 hash 碰撞的问题。


你好,我是 卢振千,一名软件工程师。欢迎你来到我的网站。