描述
给一个整数数组,找到两个数使得他们的和等于一个给定的数 target。
你需要实现的函数twoSum
需要返回这两个数的下标, 并且第一个下标小于第二个下标。注意这里下标的范围是 0 到 n-1。
假设只有一个答案!
原来做过类似的题,但是和上题有些许差别,给定的数组是递增序列,采用双指针的方法就可以解决。在看到此题时还是按照原来的思路做的:
数组先去排序,当然原来的数组也要保留,然后对排序好的数组采用双指针法找到两个值,然后在原来的数组中找到对应的下标,但是有些问题,重复的元素会不能通过(当然可以写各种逻辑修复但是代码过于复杂),而且时间复杂度过高(排序+记录原来数组+双指针法),最后舍弃。
当然也可以双层循环去遍历计算,但是太low了。
然后参考了网上的方法,代码如下
public class Solution {
/**
* @param numbers: An array of Integer
* @param target: target = numbers[index1] + numbers[index2]
* @return: [index1, index2] (index1 < index2)
*/
public int[] twoSum(int[] numbers, int target) {
// write your cod
HashMap<Integer, Integer> m = new HashMap<Integer, Integer>();
int[] res = {-1,-1};
for (int i = 0; i < numbers.length; ++i) {
if (m.containsKey(target - numbers[i])) {
res[1] = i;
res[0] = m.get(target - numbers[i]);
break;
}
m.put(numbers[i], i);
}
return res;
}
}
这思想很好,重点是 target - numbers[i] ,target=a+b变换为b=target-a,每次循环计算出差值,看看map中是否存在,存在表示有这两个数,不存在就把当前的值存入map。当初想象到哈哈。。。
我原来做过的题是这样描述的:
描述
给一个整数数组,数组按升序排序,找到两个数使得他们的和等于一个给定的数 target。
你需要实现的函数twoSum
需要返回这两个数的下标, 并且第一个下标小于第二个下标。注意这里下标的范围是 0 到 n-1。
假设只有一个答案!
这就好多了用双指针法,代码如下
public static int[] twoSum(int[] numbers, int target) {
int left =0;
int right=numbers.length-1;
int leftnum=0;
int rightnum=0;
while(right > left){
leftnum=numbers[left];
rightnum=numbers[right];
if(target>(leftnum+rightnum)){
left++;
}else if(target<(leftnum+rightnum)){
right--;
}else{
int[] i={left,right};
return i;
}
}
int[] i={-1,-1};
return i;
}
left的左指针指向0位置,right是右指针指向末尾,开始遍历,如果target大于两数之和说明两数之和比较小,则左指针右移;如果target小于两数之和说明两数之和比较大,右指针左移,知道找到等于的两数。