LeetCode题目网址:
https://leetcode-cn.com/problems/two-sum/
题目描述:
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
来源:力扣(LeetCode)
首先从题目描述中给出的几个信息
1.一组整数数组和目标值,
2.从数组中找出和为目标值的两个数组的角标值,并返回
3.不能重复使用给整数数组中的元素,并且只有一组角标符合要求
思路1.
很多人都想到通过两次for循环,找出正确的index,也就是i = 0,对应的数组织,对其他所有的元素进行遍历循环,依次进行相加得到的值是否等于target,想说的是:这样处理比较耗时并且效率很低。这样做的弊端,双重for循环,设计到数组重排,并且角标也会被打乱了,很难得到结果
思路2
是否可以通过一次for循环,就能得到咱们想要的结果呢?
答案是当然可以,思路1是确定一个数的同时在确定另外一个数,那么能不能在确定一个数的同时确定另外一个数的索引呢?也就是两个数数的不同信息
哈希表 - Map可以同时存储两种信息,并让其对应起来。
数组也可以看做一个哈希表,其索引和数值一一对应,a[i] = value;
思路是将当前数和target的差值作为Key值,将当前数的角标作为Value值,这样Key表示咱们对另外一个数的信息,而Value表示当前数的信息,
举例:target为9,当前角标0的数值为2,角标0作为Value,那么他们之间的差值是7,作为Key,两者的和就是target
package com.example.myapp;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.HashMap;
import java.util.Map;
/**
* Created by mike.
* Created on 2020/3/11.
*/
public class Code3_11_TwoNum {
@Test
public void Test() {
int[] ints = {2, 7, 11, 15};
Assert.assertArrayEquals(new int[]{0,1},twoSums(ints,9));
Assert.assertArrayEquals(new int[]{-1,-1},twoSums(ints,15));
}
private int[] twoSums(int[] nums, int target) {
int[] ints = {-1,-1};
if(ints == null || ints.length <= 1){
return ints;
}
Map<Integer, Integer> hashMap = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if(hashMap.containsKey(nums[i])){
ints[0] = hashMap.get(nums[i]);
ints[1] = i;
return ints;
}else {
hashMap.put(target - nums[i], i);
}
}
return ints;
}
//
//-1,-1
//
// i=0不包含key,false
//
// 7,0
// hashmap
//
// i = 1
//
// rs[0]=7
//
// re[1]=1
//
// rs =new int
//
// {
// 7, 1
// }
}