1、题目描述
给出一个整数数组,找出相加起来等于一个特定目标数字的两个数。
函数twoSum返回这两个相加起来等于目标值的数字的索引,且index1必须小于index2。你可以假定每个输入都有且仅有一个解决方案。
例如,输入numbers={2,7,11,15},target=9
输出:index1 = 0,index2 = 1
2、思路
解法1:
先将整个数组排序,利用Arrays.sort(),时间复杂度是O(nlogn),然后设置两个指针分别是low和high,分别指向数组的首部和尾部,求两个指针所指向的数字和,若和大于target,high--;若和小于target,low++;若等于target,返回low和high即可。时间复杂度为O(nlogn)。
代码如下:
package 算法题;
import java.util.Arrays;
public class Main5 {
public int[] twoSum(int[] nums, int target) {
int[] a = new int[2];
int[] nums1 = new int[nums.length];
System.arraycopy(nums, 0, nums1, 0, nums.length);
Arrays.sort(nums);
int low = 0;
int high = nums.length - 1;
while (low < high) {
int sum = nums[low] + nums[high];
if (sum > target) {
high--;
} else if (sum < target) {
low++;
} else {
a[0] = nums[low];
a[1] = nums[high];
break;
}
}
//将排序后数字的索引映射为原数组中数字的索引
boolean m = true;
boolean n = true;
for (int i = 0; i < nums1.length; i++) {
if (m && nums1[i] == a[0]) {
a[0] = i;
// System.out.println(i+" "+a[0]);
m = false;
continue;
}
if (n && nums1[i] == a[1]) {
a[1] = i;
n = false;
continue;
}
}
return a;
}
public static void main(String[] args) {
Main5 m = new Main5();
int[] nums = { -18, 12, 3, 0 };
int[] b = m.twoSum(nums, -6);
System.out.println(b[0] + " " + b[1]);
}
}
解法2:(推荐)
利用HashMap,把nums[i]的值放入HashMap中,value存index。遍历数组时,检查HashMap中是否已经存在和自己加一起等于target的值存在,存在的话把index取出,连同自己的index也取出,存入结果数组中返回。如果不存在的话,把自己的值和index存入HashMap中继续遍历。由于一遍遍历数组,时间复杂度为O(n)。
代码如下:
package 算法题;
import java.util.Arrays;
import java.util.HashMap;
public class Main5 {
public int[] twoSum(int[] nums, int target) {
int []a = new int[2];
HashMap<Integer,Integer> hm = new HashMap<Integer,Integer>();
for(int i=0;i<nums.length;i++) {
if(hm.containsKey(target-nums[i])) {
a[0] = hm.get(target-nums[i]);
a[1] = i;
break;
}else {
hm.put(nums[i],i);
}
}
return a;
}
public static void main(String[] args) {
Main5 m = new Main5();
int[] nums = { -18, 12, 3, 0 };
int[] b = m.twoSum(nums, -6);
System.out.println(b[0] + " " + b[1]);
}
}