难度系数:简单
要求:
nums ={1, 2, 3, 4, 5, 6, 7} targer=5
传入一串数组,求出数组之和等于目标值,则返回下标。
我这里用了两种方法,第一种最为浪费时间,时间复杂度为:O(n²)
/*
* 暴力愚蠢的办法
* */
//nums ={2,4,5,6,7,3,8} targer=5
public static int[] backSunIndex(int[] nums, int targer) {
int[] arr_index = new int[2];
//方法解析用nums[0]和所有的比,用nums[1]和后面的比
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if ((nums[i] + nums[j]) == targer) {
arr_index[0] = i;
arr_index[1] = j;
//System.out.println("i="+i);
//System.out.println("j="+j);
return arr_index;
}
}
}
return arr_index;
}
第二种办法采用了:
Map的key记录差值,value记录下标。遍历数组. 时间复杂度为:O(n)
/*
* 采用map差值做key的办法。
* */
public int[] twoSum(int[] nums, int target) {
int[] arr_index = new int[2];
// Map的key记录差值,value记录下标。遍历数组.
Map<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; i++) {
if (hashMap.containsKey(nums[i])) {
arr_index[0] = hashMap.get(nums[i]);
arr_index[1] = i;
}
hashMap.put(target - nums[i], i);
}
return arr_index;
}
算法解释:
如果Map记录了差值就说明找到了数据,获取当前数据的数组索引,同时也通过Map的value获取之前数据的数组索引,返回由两个索引构成的数组。这里核心思想就是key的选取,选择的是差值。这是由于两数加法具有确定性,已知两数之和与一个加数,那么另一个加数也是确定的。这里的思想不仅可以用于两数之和,只要两个数具有一一映射的关系,且具有确定的逆运算就可以使用,可以减少计算量。在双循环结构中,加法运算时间复杂度是二次方。而使用Map,减法的时间复杂度是一次。可以总结为使用逆运算去降低运算量。
意思就是:
int[] nums = {1, 2, 3, 4, 5, 6, 7}; int targer = 5;
i=0,key=5-1=4,value=0.
i=1,key=5-2=3,value=1.
i=2,key=5-3=2,value=2.
i=3,key=5-4=1,value=3. 此时hashMap的key已经包含nums[3]=4,返回value=0,返回i=3
算出结果:arr_index=[0,3]
全部的算法代码如下:
package com.zhm.test;
import java.lang.management.ThreadInfo;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* @title: Leatcode_test1
* @Author bige
* @Date: 2022/11/16 13:31
* @apiNote 传入一串数组,求两数最大和,返回两数下标
*/
public class Leatcode_test1 {
/*
* 暴力愚蠢的办法
* */
//nums ={2,4,5,6,7,3,8} targer=5
public static int[] backSunIndex(int[] nums, int targer) {
int[] arr_index = new int[2];
//方法解析用nums[0]和所有的比,用nums[1]和后面的比
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if ((nums[i] + nums[j]) == targer) {
arr_index[0] = i;
arr_index[1] = j;
//System.out.println("i="+i);
//System.out.println("j="+j);
return arr_index;
}
}
}
return arr_index;
}
/*
* 采用map差值做key的办法。
* */
public int[] twoSum(int[] nums, int target) {
//int[] nums = {2, 4, 5, 6, 7, 3, 8};
//int targer = 5;
int[] arr_index = new int[2];
// Map的key记录差值,value记录下标。遍历数组.
Map<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
// 5 -2 =3,key1=3. value=0
// 5-4=1, key=1,value=1
// 5-5=0 , key =0 ,value=2
for (int i = 0; i < nums.length; i++) {
if (hashMap.containsKey(nums[i])) {
arr_index[0] = hashMap.get(nums[i]);
arr_index[1] = i;
}
hashMap.put(target - nums[i], i);
}
// 如果Map记录了差值就说明找到了数据,获取当前数据的数组索引,
// 同时也通过Map的value获取之前数据的数组索引,返回由两个索引构成的数组。
// 这里核心思想就是key的选取,选择的是差值。这是由于两数加法具有确定性,
// 已知两数之和与一个加数,那么另一个加数也是确定的。这里的思想不仅可以用于两数之和,
// 只要两个数具有一一映射的关系,且具有确定的逆运算就可以使用,可以减少计算量。
// 在双循环结构中,加法运算时间复杂度是二次方。而使用Map,减法的时间复杂度是一次。
// 可以总结为使用逆运算去降低运算量。
return arr_index;
}
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5, 6, 7};
int targer = 5;
//backSunIndex(nums,targer);
System.out.println(Arrays.toString(backSunIndex(nums, targer)));
}
}