题目描述
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1] 提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案
进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/tw…
题目解析
暴力方法解析
看到这类找元素的问题,首先想到的是暴力破解,也就是通常说的循环遍历。
下面我们来看本题,如何通过使用暴力破解的方法实现。
首先遍历数组中的元素,假设当前遍历的元素nums[i]的值为x,那么还需要遍历数组中其他元素,看是否存在值为target-x的数字。如果存在那么就返回x和target-x对应的索引即可; 如果不存在值为target-x的数字,就说明没有与nums[i]对应的数字,此时应该i进行+1操作,继续遍历下一个元素。直到找到我们要找的数字,如果遍历完整个数组都没找到,说明整个数组不存在我们要找的数字,返回一个空数组即可。
步骤解析:
1、首先我们要明确,第一层循环从0 —— 数组长度-1(nums.length-1)
2、第二层循环从i+1 —— 数组长度(nums.length)
3、在第一层循环的时候,确定好一个元素,然后确定与之配对的元素值(anotherNumber)
4、在第二层的循环里,找到与第一层循环中配对的元素,并将其下标赋值到返回数组中(result)
Hash方法解析
上一种解法可以实现,但是时间复杂度比较高,那有没有更好的方法呢?
下面我们来看本题,如何通过使用Hash方法解析的方法实现。
我们可以使用HashMap,将数组中的值作为key,索引作为value,就可以O(1)的时间内找到对应的元素。我们可以创建一个哈希表,对于每一个 x,我们首先查询哈希表中是否存在 target - x,如果不存在,就将 x 插入到哈希表中,即可保证不会让 x 和自己匹配。如果哈希表中存在target-x,那么取出该值,返回即可。
步骤解析:
1、首先我们要明确,循环从0 —— 数组长度(nums)
2、边循环边找该元素对应对的目标值,如果该值不存在目标值,则将其加入到map中
3、如果存在对应的目标值,则并将其与对应值的下标赋值到返回数组中(result)
代码实现
暴力方法代码实现
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
for(int i=0;i<nums.length-1;i++){
int anotherNumber = target - nums[i];
for(int j=i+1;j<nums.length;j++){
if(anotherNumber==nums[j]){
result[0] = i;
result[1] = j;
}
}
}
return result;
}
}
Hash方法代码实现
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
map.put(nums[0],0);
for(int i=1;i<nums.length;i++){
int anotherNumber = target - nums[i];
if(map.get(anotherNumber)!=null){
result[0] = map.get(anotherNumber);
result[1] = i;
}
map.put(nums[i],i);
}
return result;
}
}