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]最简单的一种思路,两层循环,两两相加后与target比较。但是循环的起点不同,第一个元素和后面的每个元素进行比较,第二个元素也是和它之后的元素进行比较,所以外层的循环起点为0,内层的循环起点则是由外层决定,若外层为i,则内层循环起点为i+1,这样也可以保证,不重复利用数组中同样的元素。
class Solution { public int[] twoSum(int[] nums, int target) { int[] result = new int[2]; for (int i = 0; i < nums.length; i++) { for (int j = i + 1; j < nums.length; j++) { if (nums[i] + nums[j] == target) { result[0] = i; result[1] = j; } } } return result; } }暴力方法之所以要循环两次,是因为我们需要找两个数的下标,采用哈希表的方法,在循环过程中存储下标,可以省去嵌套一次循环,但是找结果的方式与暴力方式不太一样。
class Solution { public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { int complement = target - nums[i]; if (map.containsKey(complement)) { return new int[] { map.get(complement), i }; } map.put(nums[i], i); } throw new IllegalArgumentException("No two sum solution"); } }上面的暴力方法,是从前往后找另外一半,找到立刻返回,比如
int nums[] = new int[]{2, 7, 11, 15};若target目标值为17,执行过程:
i,j计算结果是否匹配0,19NO0,213NO0,317YES若是用哈希表的方式,可以理解为从当前循环点往前找另外一半,利用的是2+3=5,3+2=5,加法的交换律,不管从前往后还是从后往前,都是OK的。 执行过程:
i是否匹配单次循环结束后map0NO(2, 0)1NO(2, 0) , (7,1)2NO(2,0) , (7,1) , (11,3)3YES