算法题004 -- [给定一个整数的数组nums,返回相加为target的两个数字的索引值] by java

版权声明:本文为博主原创文章,未经博主允许不得转载。 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,也是可以做到的。

猜你喜欢

转载自blog.csdn.net/cjh_android/article/details/83789101
今日推荐