1两数之和-数组
描述
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。
你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
实例
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
题解
最容易想到的是暴利破解,遍历数组中任意两元素之和,并与目标值进行比较,若正确则输出.
进一步考虑,当知道第一个数和目标值时,第二个数值可以由第一个数推断获得,即将每两个元素都要进行的求和运算改成了只在第一层循环中存在的求差操作.
public static int[] twoSum1(int[] nums, int target) {
int nextValue = 0;
for (int i=0;i<nums.length;i++){
nextValue = target - nums[i];
for (int j=i+1;j<nums.length;j++){
if (nextValue == nums[j]){
int[] result = new int[2];
result[0] = i;
result[1] = j;
if (i == j)
continue;
return result;
}
}
}
return null;
}
由于需要两次遍历所有元素,是O(n^2)的时间复杂度,于是可以考虑能否增加空间复杂度来减小时间代价.由于HashMap 的查找时间是一个常数,我们可以在第一遍遍历时将所有元素存入HashMap中,再在第二次遍历时直接查找是否存在对应的第二个数,从而缩短时间.
public static int[] twoSum2(int[] nums, int target) {
HashMap<Integer,Integer> indexFind = new HashMap<>();
for (int i=0;i<nums.length;i++){
indexFind.put(nums[i],i);
}
for (int i=0;i<nums.length;i++){
if (indexFind.get(target-nums[i]) != null){
int[] result = new int[2];
result[0] = i;
result[1] = indexFind.get(target-nums[i]);
if (i == result[1])
continue;
return result;
}
}
return null;
}
通过此方法,可以将29个测试用例的22 ms缩减到8 ms.