题目描述
给定一个整数数组 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]
解题方法
1.暴力拆解
暴力拆解很好理解,两个for循环,拿第一个数与其他进行比较,最终得到正解返回
public class TwoNumberSum {
public static void main(String[] args) {
TwoSumTest1 twoSumTest = new TwoSumTest1();
int[] num = {2, 5, 11, 15, 6, 8, 7};
System.out.println(Arrays.toString(twoSumTest.twoSum(num, 9)));
// 最终返回结果[0, 6]
}
}
/**
* 暴力拆解
*/
class TwoSumTest1 {
public int[] twoSum(int[] nums, int target) {
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 new int[]{};
}
}
2.二分法
二分法,可以理解为 a + b = c 现在我们可以确定 a 和 c,要想找到b就只需要 c - a 即可,然后就可以从数组的两头开始找起
public class TwoNumberSum {
public static void main(String[] args) {
TwoSumTest2 twoSumTest = new TwoSumTest2();
int[] num = {2, 5, 11, 15, 6, 8, 7};
System.out.println(Arrays.toString(twoSumTest.twoSum(num, 9)));
// 最终返回结果[0, 6]
}
}
/**
* 二分法
*/
class TwoSumTest2{
public int[] twoSum(int[] nums, int target) {
/**
* 假如只有两个数,那么就直接返回
*/
int[] result = {0, 1};
if (nums.length <= 2) {
return result;
}
/**
* 数组里的数大于两个数
*/
for (int i = 0; i < nums.length - 1; i++) {
/**
* [2, 7, 11, 15]
* 先锁定一个数,也就是第一个 2
*/
result[0] = i;
/**
* 这里可以理解为:a + b = c 那么a和c确定了就可以确定b 所以x就是那个b
*/
int x = target - nums[i];
/**
* 接下来就是开始找 b
* 这里巧妙的运用了二分法,从两头开始找起如果符合就直接返回
* (从两头往中间找)
*/
for (int j = i + 1, k = nums.length - 1; j <= k; j++, k--) {
if (nums[j] == x) {
result[1] = j;
return result;
}
if (nums[k] == x) {
result[1] = k;
return result;
}
}
}
return result;
}
}
3.哈希表
哈希表实际上采用的就是containsKey()这个方法来找key,可以说是先将数组存到哈希表中,然后在通过找b来找到对应的结果
public class TwoNumberSum {
public static void main(String[] args) {
TwoSumTest1 twoSumTest = new TwoSumTest1();
int[] num = {2, 5, 11, 15, 6, 8, 7};
System.out.println(Arrays.toString(twoSumTest.twoSum(num, 9)));
// 最终返回结果[0, 6]
}
}
/**
* 哈希表法
*/
class TwoSumTest3{
public int[] twoSum(int[] nums, int target) {
/**
* [2, 5, 11, 15, 7] 9
* 还是 a + b = c
* 先定义一个hashMap 利用hashMap中的containKey方法来确定b
*/
Map<Integer, Integer> hashMap = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
/**
* 第一次进入循环hashMap是空的,什么也没有,然后put第一个数
* 第二次进循环 得到9 - 5 = 4 然后和hashMap里的key进行比较
* 此时hashMap{(2,0)}
* 第三次进循环 得到9 - 11 = -2 然后和hashMap里的key进行比较
* 此时hashMap{(2,0),(5,1)}
* 第四次进循环 得到9 - 15 = -6 然后和hashMap里的key进行比较
* 此时hashMap{(2,0),(5,1),(11,2)}
* 第五次进循环 得到9 - 7 = 2 然后和hashMap里的key进行比较
*/
if (hashMap.containsKey(target - nums[i])) {
return new int[]{hashMap.get(target - nums[i]), i};
}
hashMap.put(nums[i], i);
}
return new int[]{};
}