1. 描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
2. 示例
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
3. 分析
目标:从数组中寻找两个数,使得它们的和等于一个给定值。
题目中给出了两点限制。第一点是对于给定值,数组中只会有一种情况,使得两个数的和满足条件;第二点是,数组中的同一个元素不能使用两遍。
3.1. 暴力搜索
对数组中的所有值,进行两两匹配,它们的和等于给定值,就找到这两个数了。
需要两层遍历,每一层遍历搜索一个数;当它们的和等于给定值时,停止搜索。
时间复杂度:最坏的情况下是 O ( n 2 ) O(n^2) O(n2)。
3.2. 字典匹配
在知道目标值的情况下,一个数的补数是可以确定的。
举个例子,现在要求 2 个数的和为9,其中一个数是 1, 另外一个数是多少?
另一个数是 8(9 - 1),也即是 num2 = target - num1。
我们可以利用这一性质。
我们需要访问一遍数组,设当前访问的数组元素为 nums[i], 在一个字典中查找 nums[i] 是否已经存在(key)。
若不存在,则将(target - nums[i])作为字典的键(key),下标 i 作为字典的值(value),插入到字典中;
若已经存在,说明(target - nums[i])在数组 nums 中必然存在,且已经访问过,它的下标可以从字典中得到。
这样,只需要一次遍历就可以得到这两个数。
时间复杂度:最坏的情况下是 O ( n ) O(n) O(n)。
4. 代码
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] indices = new int[2];
out:
for(int i = 0; i < nums.length; ++i)
{
for(int j = i + 1; j < nums.length; ++j)
{
if(nums[i] + nums[j] == target)
{
indices[0] = i;
indices[1] = j;
break out;
}
}
}
return indices;
}
}
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] indices = new int[2];
Map<Integer, Integer> dict = new HashMap<>();
for(int i = 0; i < nums.length; ++i)
{
if(dict.containsKey(nums[i]))
{
indices[0] = dict.get(nums[i]);
indices[1] = i;
break;
}
else
{
dict.put(target - nums[i], i);
}
}
return indices;
}
}
5. 验证
6. 出处
- LeetCode 1. 两数之和
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。