[LeetCode] Two Sum

题目链接:https://oj.leetcode.com/problems/two-sum/

问题:

Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would have exactly one solution.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,

return [0, 1].

 

方法一:暴力破解

思路:计算所有数两两组合的和,然后与target对比。

 1     public int[] twoSum(int[] nums, int target) {
 2         int index1, index2;
 3         int[] index = new int[]{0,1};
 4         for(int i = 0; i < nums.length; i++){
 5             for(int j = i + 1; j < nums.length; j++){
 6                 if(target == (nums[i] + nums[j])){
 7                     index[0] = i;
 8                     index[1] = j;
 9                     return index;
10                 }
11             }    
12         }
13      throw new IllegalArgumentException("No two sum solution");

14 }

时间复杂度:O(n2),空间复杂度:O(1)

 

方法二:使用Hash Table

思路:使用hashMap,将数组中元素的值与其对应的索引分别对应键值对key和value,查找时间复杂度降低为O(1),运用Hash table需要O(n)的时间复杂度。

 1     public int[] twoSum(int[] numbers, int target){
 2         Map<Integer, Integer> map = new HashMap<>();
 3         for(int i = 0; i < numbers.length; i++){
 4             int x = numbers[i];
 5             if(map.containsKey(target - x)){
 6                 return new int[] {map.get(target - x) + 1,i + 1};
 7             }
 8             map.put(x, i);
 9         }
10         throw new IllegalArgumentException("No two sum solution");
11     }

时间复杂度:O(n),空间复杂度:O(n)

 

扩展问题:

问题一:在原题的基础上,增加限制条件(输入数组已经按升序排列)

方法一:二分查找

对于数组中每个元素x,用二分查找是否存在 target - x,查找时间复杂度为O(logn),总时间复杂度为O(nlogn)

 1         public int[] twoSortedSum(int[] numbers, int target){
 2         //Assume input is already sorted
 3         for(int i = 0; i < numbers.length; i++){
 4             int j = bsearch(numbers, target - numbers[i], i+1);
 5             if(j != -1){
 6                 return new int[] { i + 1, j + 1 };
 7             }
 8         }
 9         throw new IllegalArgumentException("No two sum solution");
10 
11     }
12 
13     //binary search
14     private int bsearch(int[] A, int key, int start){
15         int L = start;
16         int R = A.length - 1;
17         while(L < R){
18             int M = (L + R) / 2;
19             if(A[M] < key){
20                 L = M + 1;
21             }else{
22                 R = M;
23             }
24         }
25         return (L == R && A[L] == key) ? L : -1;
26     }

时间复杂度:O(nlogn),空间复杂度:O(1)

 

方法二:双指针法

假设两个指针i和j分别指向第i个元素Ai和第j个元素Aj,Ai + Aj的值有一下三种情况

1)Ai + Aj  > target 

不能增加i,只能减小j。因为增加i会使Ai + Aj 的值更大

2)Ai + Aj  > target 

不能减小i,只能增加j。因为减小j会使Ai + Aj 的值更小

3)Ai + Aj  == target 

可以得到返回结果[i,j]

    public int[] twoSortedSum2(int[] numbers, int target){
        //Assume input is already sorted
        int i = 0; 
        int j = numbers.length - 1;
        while(i < j){
            int sum = numbers[i] + numbers[j];
            if(sum < target){
                i++;
            }else if(sum > target){
                j--;
            }else{
                return new int[] {i+1, j+1 };
            }
        }
        throw new IllegalArgumentException("No two sum solution");
    }

时间复杂度:O(n),空间复杂度:O(1)

 

 

posted @ 2016-08-17 16:55  沫沫_fun  阅读(118)  评论(2)    收藏  举报