题目描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
题目分析
暴力搜索的方法是遍历所有的两个数字的组合,然后算其和,这样虽然节省了空间,但是时间复杂度高。
一般来说,为了提高时间的复杂度,需要用空间来换,这算是一个 trade off 吧,但这里只想用线性的时间复杂度来解决问题,就是说只能遍历一个数字,那么另一个数字呢,可以事先将其存储起来,使用一个 HashMap,来建立数字和其坐标位置之间的映射。
由于 HashMap 是常数级的查找效率,这样在遍历数组的时候,用 target 减去遍历到的数字,就是另一个需要的数字了,直接在 HashMap 中查找其是否存在即可。
暴力求解
暴力法很简单,遍历每个元素 xx,并查找是否存在一个值与 target - xtarget−x 相等的目标元素。
public int[] twoSum(int[] nums, int target) {
//注意判空
if(nums==null || nums.length==0){
return null;
}
for(int i=0;i<nums.length;i++){
for(int j=i+1;j<nums.length;j++){
if(nums[i]+nums[j]==target){
return new int[]{i,j};
}
}
}
return null;
}
复杂度分析:
时间复杂度:O(n^2)
对于每个元素,我们试图通过遍历数组的其余部分来寻找它所对应的目标元素,这将耗费 O(n)O(n) 的时间。因此时间复杂度为 O(n^2)。
空间复杂度:O(1)。
哈希表两次遍历
注意要判断查找到的数字不是第一个数字,比如 target 是4,遍历到了一个2,那么另外一个2不能是之前那个2,整个实现步骤为:先遍历一遍数组,建立 HashMap 映射,然后再遍历一遍,开始查找,找到则记录 index。
哈希表中对应的存储,key是元素,value是其下标,这样在二次遍历时可以通过对比下标排除同一个元素。文章来源:https://www.toymoban.com/news/detail-424811.html
public int[] twoSum(int[] nums, int target) {
if(nums==null || nums.length==0){
return null;
}
HashMap<Integer,Integer> map=new HashMap();
for(int i=0;i<nums.length;i++){
map.put(nums[i],i);
}
//两次遍历
for(int i=0;i<nums.length;i++){
int sub=target-nums[i];
if(map.containsKey(sub) && map.get(sub)!=i){
return new int[]{i,map.get(sub)};
}
}
return null;
}
哈希表一次遍历
这种方式不需要考虑额外的重复判重。文章来源地址https://www.toymoban.com/news/detail-424811.html
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
//注意是target作为减数
int diff = target - nums[i];
if (map.containsKey(diff)) {
return new int[] { map.get(diff), i };
}
map.put(nums[i], i);
}
throw new IllegalArgumentException("No two sum solution");
}
}
到了这里,关于LeetCode 1. Two Sum 两数之和的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!