- 题目描述:(LeetCode中国)
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 - 比如:给定一个数组[1,3,6,7],target=13,返回的数组应该为[2,3](6+7=13)
- 解法1:暴力解法,也是最容易想到的
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result=new int[2];
for(int i=0;i<nums.length;i++){
for(int j=i+1;j<nums.length;j++){
if(nums[i]+nums[j]==target){
result[0]=i;
result[1]=j;
return result;
}
}
}
throw new IllegalArgumentException("数组中没有两数满足要求");
}
}
这种解法的时间复杂度为O(n^2),空间复杂度为O(1)(关于时空复杂度的知识,可以看这位博主的文章)
- 解法2:两遍哈希表
先把数组中的数据和他对应的下标保存在一个hash表中,然后再遍历一次,查找temp=target-nums[j]有没有在hash表中,特别地:如果当前nums[j]刚刚好是target的一半,我们要保证temp不是nums[j]本身,因此还要比较他们的下标,下标不同并且能在表中找到temp,说明就是我们要找的数据。
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map=new HashMap<>();
for(int i=0;i<nums.length;i++){
map.put(nums[i],i);
}
for(int j=0;j<nums.length;j++){
int temp=target-nums[j];
if(map.containsKey(temp)&&map.get(temp)!=j){//哈希表中包含temp,并且temp对应的下标不是j
return new int[] {j,map.get(temp)};
}
}
throw new IllegalArgumentException("数组中没有两数满足要求");
}
}
时间复杂度:O(n),空间复杂度:O(n)
- 解法3:一遍哈希表
同上面的思路,我们可以在将数据放入hash表的过程中,在放入之前我们先比较temp=target-nums[i]是否在表中存在,如果存在的话我们直接返回不必再放入表中。
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map=new HashMap<>();
for(int i=0;i<nums.length;i++){
int temp=target-nums[i];
if(map.containsKey(temp)){//哈希表中包含temp,这时temp必不可能是nums[i]
return new int[] {i,map.get(temp)};
}
map.put(nums[i],i);
}
throw new IllegalArgumentException("数组中没有两数满足要求");
}
}