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].
咋眼一看题目,就感觉可以用暴力搜索,这个算法的时间复杂度是O(n^2)。
暴力法:
class Solution {
public int[] twoSum(int[] nums, int target) {
int length = nums.length;
int index1 = 0;
int index2 = 0;
for(int i=0; i<length; i++){
for(int j=i+1; j<length; j++){
if(nums[i] + nums[j] == target){
index1 = i;
index2 = j;
}
}
}
int[] array = new int[]{index1, index2};
return array;
}
}
由于暴力搜索的方法是遍历所有的两个数字的组合,然后算它们的和,这样虽然节省了空间,但是时间复杂度高。一般来说,我们为了提高时间的复杂度,需要用空间来换,如果我们只想用线性的时间复杂度来解决问题,那么就是说只能遍历一个数字,那么另一个数字呢,我们可以事先将其存储起来,使用一个 HashMap,来建立数字和其坐标位置之间的映射,我们都知道 HashMap 是常数级的查找效率,这样,我们在遍历数组的时候,用 target 减去遍历到的数字,就是另一个需要的数字了,直接在 HashMap 中查找其是否存在即可,注意要判断查找到的数字不是第一个数字,比如 target 是4,遍历到了一个 2,那么另外一个 2 不能是之前那个 2,整个实现步骤为:先遍历一遍数组,建立 HashMap 映射,然后再遍历一遍,开始查找,找到则记录index。
public class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
int[] result = new int[2];
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], i);
}
for (int i = 0; i < nums.length; i++) {
int t = target - nums[i];
if (map.containsKey(t) && map.get(t) != i) {
result[0] = i;
result[1] = map.get(t);
break;
}
}
return result;
}
}
两个算法的性能差距明显,LeetCode 的 OJ 结果如下: