首页 > 技术文章 > 1. Two Sum[LeetCode 简单 by 大志]

liushen 2017-06-29 09:38 原文

  1. 二数之和

题目

English

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

翻译

一个整数数组,如果数组中的二个数字之和等于特定值,返回这二个数的索引。
假定肯定有解,但是你只能使用每个元素最多一次。
例:

给定数组: nums = [2, 7, 11, 15], 二数之和为:9,

因为:nums[0] + nums[1] = 2 + 7 = 9,
所以返回: [0, 1].

详细解答

1. for 循环

标准的做法,第一印象,数组nums中的2数之和等于target,那就穷举,将数组的任意2数相加,判断和是否等于target,是则返回这个数字的索引。
实现如下:

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

该实现方式的时间复杂度为:O(n2), 空间复杂度: O(n)
即使中规中矩的做法,运行时间210ms也击败了50%的已通过代码的执行时间,还不错。下面来优化下

2. Map 实现

ES6为我们提供了Map数据结构。它是一个”value-value”的对应。如果需要“键值对”的数据结构,Map是一个很合适的数据结构。
这里我们先用ES5的方式实现,定义一个对象,将nums的值作对对象的属性,而index作为对象属性所对应的值。

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


该实现方式的时间复杂度为:O(n), 空间复杂度: O(n)

3. 优化版 map 实现

var twoSum = function(nums, target) {
    const map = new Map();
	for (let [index, elem] of nums.entries()) {
		var complement = target - elem
		if (map.has(complement)) {
			return [map.get(complement), index];
		}
		map.set(elem, index);
	}
};

该实现方式的时间复杂度为:O(n), 空间复杂度: O(n)

推荐阅读