2.1.7 Two Sum

Link: https://oj.leetcode.com/problems/two-sum/

Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

Approach I: Usehashset

Time: O(n), Space: O(n)

这是我写的代码。有问题。不能这样循环两遍,否则会有问题:

Input: [3,2,4], 6
Output: 1, 1
Expected: 2, 3
这里,6 - 3 = 3。所以第二遍for loop, hashset包含了3,但是这个3不是input里的3.

public class Solution {
    public int[] twoSum(int[] numbers, int target) {
        int[] result = new int[2];
        HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
        for(int i = 0; i < numbers.length; i++){
            table.put(target - numbers[i], i);
        }
        for(int i = 0; i < numbers.length; i++){
            if(table.containsKey(numbers[i])){
                result[0] = table.get(numbers[i])+1;
                result[1] = i+1;
                return result;
            }
        }
        return result;
    }
}
正确解法:一遍for loop 

public class Solution {
    public int[] twoSum(int[] numbers, int target) {
        int[] result = new int[2];
        if(numbers == null || numbers.length < 2) return result;
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        for(int i = 0; i < numbers.length; i++){
            if(map.containsKey(numbers[i])){
                result[0] = map.get(numbers[i])+1;
                result[1] = i+1;
                return result;
            }
            else{
                map.put(target - numbers[i], i);
            }
        }
        return result;
    }
}

Approach II: 先排序,然后左右夹逼。

Time: O(nlogn)+O(n) = O(nlogn).

public class Solution {
    public class Element{
        int index;
        int val;
        public Element(int index, int val){
            this.index = index;
            this.val = val;
        }
    }
    
    public int[] twoSum(int[] numbers, int target) {
        int[] result = new int[2];
        if(numbers == null || numbers.length < 2) return result;
        
        Element[] e = new Element[numbers.length];
        for(int i = 0; i < numbers.length; i++){
            e[i] = new Element(i, numbers[i]);
        }
        Comparator<Element> comparator = new Comparator<Element>(Element a, Element b){
            if(a.val > b.val) return 1;
            else if(a.val == b.val) return 0;
            else return -1;
        }
        int i = 0;
        int j = numbers.length - 1;
        while(i < j){
            int sum = e[i].val + e[j].val;
            if(sum == target){
                result[0] = Math.min(e[i].index, e[j].index)+1;
                result[1] = Math.max(e[i].index, e[j].index)+1;
                return result;
            }
            else if(sum < target){
                i++;
            }
            else{
                j--;
            }
        }
        return result;
    }
}


上面代码里的Comparator的写法是错误的,应该是:
Arrays.sort(numbers, 
            new Comparator<Element>(){
                public int compare(Element a, Element b){
                    if(a.val > b.val) return 1;
                    else if(a.val == b.val) return 0;
                    else return -1;
                }});

or

     class ValComparator implements Comparator<Element> {
          public int compare(Element a, Element b) {
              if(a.val == b.val) return 0;
              else if(a.val > b.val) return 1;
              else return -1;
          }
      }

Arrays.sort(elementArr, new ValComparator());

2014.11.3

HashMap的解法没问题。todo:Comparator解法


2016.1.23

Below is wrong. 排序以后,原来的index就改变了,所以不能用left,right作为返回的index. 因此如果要用排序,必须先把index,val都存起来。

   public int[] twoSum(int[] nums, int target) {
      //sort?
      Collections.sort(nums, new Comparator());
      //one from left, one from right
      int[] result = new int[2];
      int left = 0;
      int right = nums.length-1;
      while(left < right) {
          if(nums[left] + nums[right] == target) {
              result[0] = left;
              result[1] = right;
              return result;
          }
          else if(nums[left] + nums[right] < target) {
              left++;
          }
          else{
              right--;
          }
      }
      return result;
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值