版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cjh_android/article/details/83789101
题目
给定一个整数的数组nums,返回相加为target的两个数字的索引值。
假设每次输入都只有一个答案,并且不会使用同一个元素两次。
举例:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
代码
package algorithm4;
import java.util.HashMap;
import java.util.Map;
public class Algorithm4 {
public static void main(String[] args) {
int[] nums = {2, 5, 11, 7, 1, 9};
int[] tartgetNum = getTargetNumsByMapOptimize(nums, 10);
System.out.println(tartgetNum[0] + " ::: " + tartgetNum[1] );
}
/**方法一:
* 思路:通过两层循环,拿出每一个元素,与在它之后的元素相加
* 优点:思路简单
* 缺点:时间复杂度为 O(n^2)
*
* @param nums
* @param target
* @return
*/
public static int[] getTargetNums(int[] nums, int target) {
int[] tartgetNum = new int[2];
for(int i=0; i<nums.length -1; i++) {
//优化,只考虑i位置后面的元素,前面的元素其实已经被过滤掉了
for(int j= i+1; j<nums.length;j++) {
if((nums[i] + nums[j]) == target) {
tartgetNum[0] = i;
tartgetNum[1] = j;
return tartgetNum;
}
}
}
return tartgetNum;
}
/**方法二:
* 思路:既然在数组中 target=a+b,
* 那么如果利用b来记录a的位置,
* 在遍历的过程中,判断元素是否被记录过,
* 如果被记录过,那么就说明该元素就是我们想要找的
* 最后再通过该元素查找出a的位置。
* 优点:思路简单,时间复杂度只有 O(2n)->O(n)
* 缺点:不易察觉的边界条件 index != i ;
* 设有元素K1,而 target = 2 * K1,
* target = K1 + K2; K2 = K1
* 上面的假设就会导致 K2 对应的位置也就是 K1自己的位置
* 在第二次遍历的过程中就会出现寻找到的位置是同一个
*
* @param nums
* @param target
* @return
*/
public static int[] getTargetNumsByMap(int[] nums, int target) {
int[] tartgetNum = new int[2];
HashMap<Integer, Integer> map = new HashMap<>();
//第一次循环
for(int i=0; i<nums.length; i++) {
int dValue = target - nums[i];
map.put(dValue, i);
}
for(int i=0; i<nums.length; i++) {
Integer index = map.get(nums[i]);
// index != i 这个边界条件十分重要
if(index != null && index != i) {
tartgetNum[0] = index;
tartgetNum[1] = i;
return tartgetNum;
}
}
return tartgetNum;
}
/**方法三:
* 思路:在方法而的基础上,继续优化了时间复杂度;
* 将两次循环变为一次:
* 既然设定了 target = a+b;
* 在遍历的同时,将当前元素差值记录下来,依然对应坐标
* 那么在之后的遍历过程中,必然会找到对应的元素
* 此时map中存储的value,for循环中的i,就是要找的index了
* 与方法二不同的是,方法二之所以会有边界问题的存在,
* 就是因为第二次遍历过程中,从头开始
* 而方法三则是一路向前,绝不回头,不会出现方法二的漏洞
* 优点:思路简单,时间复杂度只有 O(n)
* 缺点:非要说缺点的话,也只能说牺牲空间复杂度,优化时间复杂度
* @param nums
* @param target
* @return
*/
public static int[] getTargetNumsByMapOptimize(int[] nums, int target) {
int[] result = new int[2];
Map<Integer,Integer> map = new HashMap();
for(int i=0; i<nums.length; i++){
if(map.containsKey(nums[i])){
result[0] = i;
result[1] = map.get(nums[i]);
return result;
}
map.put(target - nums[i], i);
}
return result;
}
}
思路扩展:
其实不一定要用map,在方法二、三中,只是引入了Map的结构,如果是一个String,也是可以做到的。