题目
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
翻译
给定一个整数数组,找出其中两个数满足相加等于你指定的目标数字。
每个输入只有一个唯一解。相同的元素不能用两次。
解题思路
那么本题呢双重循环的方法在这里就不说了。主要展示一下借助HashMap实现。以及要考虑的问题。
思路还是比较简单的。首先我们把所有元素放到map中。key为元素本身。value为元素在数组中的索引值。放到map中是因为方便查找元素的位置。同时哈希表查找元素的时间复杂度是O(1)级别的。
然后再遍历一边数组。查找map中对应的那个元素。
代码如下
// 1. Two Sum
// https://leetcode.com/problems/two-sum/description/
// 时间复杂度:O(n)
// 空间复杂度:O(n)
public class Solution2 {
public int[] twoSum(int[] nums, int target) {
HashMap record = new HashMap();
for(int i = 0 ; i < nums.length ; i ++)
record.put(nums[i], i);
for(int i = 0 ; i < nums.length; i ++){
if(record.containsKey(target - nums[i]))
if(record.get(target - nums[i]) != i){ //不能是同一个的元素相加等于目标值
int[] res = {i, record.get(target - nums[i])};
return res;
}
}
throw new IllegalStateException("the input has no solution");
}
}
题到这里就结束了吗?那么有没有想过这么一种可能。这个数组中假如有两个值都为a的元素。那么我们将数组中的元素放到map中时。后面的那个a就将前面那个a覆盖了。a对应的value值为后面那个a的索引。如图:
如果此题的目标值刚好是2a。就是这两个a相加呢?其实这种情况也没有关系。想想当我们第二次遍历数组时。首先肯定遍历到的是数组中的第一个a。此时我们查找map时。找到的另一个值也是a。而map中的这个a刚好使我们数组中的第二个a。因为map中第一个a已被第二个覆盖掉了。所以取当前数组中的a的索引。同时取map中a的索引。就刚好是我们要的答案。
这里提供递归解法。
KSum解决方法:
解决这类问题有两个方法:
KSum java代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
public class KSum {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//int[] s = new int[] {1,0,-1,0,-2,2 };
int[] s = new int[]{-500,-490,-471,-456,-422,-412,-406,-398,-381,-361,-341,-332,-292,-288,-272,-236,-235,-227,-207,-203,-185,-119,-59,-13,4,5,46,72,82,91,92,130,130,140,145,159,187,207,211,226,239,260,262,282,290,352,377,378,386,405,409,430,445,478,481,498};
System.out.println(" A solution set is: ");
List> listArray = new ArrayList>();
listArray = kSum(s,-3213);
for (int i = 0; i < listArray.size(); i++) {
System.out.println(listArray.get(i));
}
}
public static List> kSum(int[] nums, int target) {
List> result = new ArrayList>();
Arrays.sort(nums);
result = recursionRoutin(nums,0,4,0);
return result;
}
public static List> recursionRoutin(int[] nums,int begin,int k,int target){
HashSet> elementSet = new HashSet>();
List> result = new ArrayList>();
List> subResult = new ArrayList>();
//Recursion Base
if(k == 2){
int left = begin;
int right = nums.length - 1;
while(left < right){
int sum = nums[left] + nums[right];
if(sum == target){
List taplet = new ArrayList();
taplet.add(nums[left]);
taplet.add(nums[right]);
//Avoid reduplication
if(!elementSet.contains(taplet)){
result.add(taplet);
elementSet.add(taplet);
}
left ++;
right --;
}else if(sum < target){
left ++;
}else{
right --;
}
}
return result;
}else{
for(int i = begin;i < nums.length - k - 1;i ++){
subResult = recursionRoutin(nums,i + 1,k - 1,target - nums[i]);
//System.out.println(k + " " + subResult);
if(!subResult.isEmpty()){
for(int j = 0;j < subResult.size();j ++){
subResult.get(j).add(nums[i]);
result.add(subResult.get(j));
}
}
}
}
return result;
}
}
参考博客:
https://blog.csdn.net/github_27609763/article/details/47728809
https://blog.csdn.net/qq_26437925/article/details/52787136 (方法多)
http://lib.csdn.net/article/datastructure/13655
https://www.jianshu.com/p/f8277161041c