领扣刷题之两数之和!

描述

给一个整数数组,找到两个数使得他们的和等于一个给定的数 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 m = new HashMap();
        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小于两数之和说明两数之和比较大,右指针左移,知道找到等于的两数。

你可能感兴趣的:(算法)