您的位置:首页 > 其它

LeetCode - 两数之和

2018-03-04 15:56 211 查看
LeeetCode题目网址:https://leetcodechina.com/problems/two-sum/description/

题目描述:

给定一个整数数列,找出其中和为特定值的那两个数。

你可以假设每个输入都只会有一种答案,同样的元素不能被重用。

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

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


https://github.com/biezhihua/LeetCode

题目思路:

仔细的阅读题目获取有效信息。

信息1:从“给定一个整数数列”可以得知,预先给的数组可能是无序状态。

信息2:从“和为特定值的两个数”可以得知,预先给一个Target值,让们找出该无序数组中是否存在两数其和为Target。

信息3:再根据示例要求返回该无序数组中两数的索引值,可以知道在该题目中无法使用先排序的解法,因为排序会导致元素从排,同时索引会被打断。

信息4:两数之和结果唯一,且不能重用同一个数。

思路1:

先确定两数中的一个数,再去确定另外一个数,然后判断两数之和与Target的关系。该解法需要两层
for
循环,第一个
for
循环用于确定第一个数,第二个
for
循环用于确定第二个数,然后在最内部做逻辑判断。

虽然此法简单,但是时间复杂度是O(n2)O(n2)。显然不是最优解法。(谁都能直接想到的解法往往都不是最优解法)。

思路2:

在思路1中“先确定一个数再确定另一个数”显然不是我们继续思考的方向了,因为一次
for
能确定一个数和索引,那么能不能在确定索引的同时确定另外一个数的索引呢?也就是如何同时表示两个维度的信息(也就是两个数的信息)。

哈希表 - Map可以同时存储两种信息,并让其对应起来。

数组也可以看做一个哈希表,其索引和数值一一对应,a[i] = value;

我们可以在Map中将当前数与Target值得差值作为Key,将当前数的索引作为Value。这样就同时表示了两个维度的信息,Key代表我们对另外一个数的要求,Value代表当前数的索引。

举个例子,Target为9,当前索引为0数为2,那么差值为7。只要后面数组中存在数值为7,那么两者和就为Target。

该思路的核心在于如何在一次操作中确定两个数的信息。这样遍历一遍就能得到结果,其时间复杂度为O(n)O(n)。

题目解法:

public class Code_3_4_TwoSum {

@Test
public void test() {
int[] nums = new int[]{2, 7, 11, 15};
Assert.assertArrayEquals(new int[]{0, 1}, twoSum(nums, 9));
Assert.assertArrayEquals(new int[]{-1, -1}, twoSum(nums, 10));
}

int[] twoSum(int[] nums, int target) {
int[] rs = new int[]{-1, -1};

if (nums == null || nums.length <= 1)
return rs;

Map<Integer, Integer> hashMap = new HashMap<>();

for (int i = 0; i < nums.length; i++) {
if (hashMap.containsKey(nums[i])) {
rs[0] = hashMap.get(nums[i]);
rs[1] = i;
return rs;
} else {
hashMap.put(target - nums[i], i);
}
}

return rs;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: