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;
    }


發佈了153 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章