题目描述

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

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

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

所以返回 [0, 1]

解法

1. 暴力法

由于每种输入只会对应一种答案,使用双重循环遍历,若相加得到的值等于target,则返回对应的下标数组。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
for (int i = 0; i < nums.length - 1; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (target == nums[i] + nums[j]) {
result[0] = i;
result[1] = j;
return result;
}
}
}
return result;
}
}

复杂度分析

  • 时间复杂度:$O(n^2)$

    对长度为n的数组进行了双重遍历,所以时间复杂度是$O(n^2)$

  • 空间复杂度:$O(1)$

    没有使用额外的内存空间,所以空间复杂度为$O(1)$

2. HashMap

为了对时间复杂度进行优化,需要一种更有效的方式来进行检索。保持数组中每个元素和其索引相互对应的最好方法是什么?哈希表。

可以遍历数组,将对应的键值对存入哈希表。然后判断哈希表中是否存在$target-nums[i]$,若存在,则直接返回索引。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.HashMap;

class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
HashMap<Integer,Integer> hash = new HashMap<Integer, Integer>();

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

复杂度分析

  • 时间复杂度:$O(n)$

    只对长度为n的数组进行了一次遍历。

  • 空间复杂度:$O(n)$

    所需的额外空间取决于哈希表中存储元素的个数。

参考