leetcode 167. Two Sum II

来源:互联网 发布:睡眠时间 知乎 编辑:程序博客网 时间:2024/06/06 13:13

Given an array of integers that is already sorted in ascending order, 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 and you may not use the same element twice.

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

这个问题,如果单纯用两个pointer,第一个从左到右,第二个每次从第一个位置开始遍历,这种方法没有技术含量,也会TLE。我用的是map,但是时间复杂度也不咋地。

package leetcode;import java.util.Arrays;import java.util.HashMap;import java.util.Map;public class Two_Sum_II__Input_array_is_sorted_167 {public int[] twoSum(int[] numbers, int target) {int[] result=new int[2];Map<Integer, Integer> map=new HashMap<Integer, Integer>();for(int i=0;i<numbers.length;i++){if(map.get(numbers[i])==null){map.put(numbers[i], i);}}for(int i=0;i<numbers.length;i++){int needNum=target-numbers[i];if(needNum==numbers[i]){result[0]=i+1;result[1]=i+2;break;}if(map.get(needNum)!=null){result[0]=i+1;//因为both index1 and index2 are not zero-basedresult[1]=map.get(needNum)+1;//所以index要加1break;}}return result;}public static void main(String[] args) {// TODO Auto-generated method stubTwo_Sum_II__Input_array_is_sorted_167 t=new Two_Sum_II__Input_array_is_sorted_167();int[] nums=new int[]{0,0,3,4};int target=9;System.out.println(Arrays.toString(t.twoSum(nums, target)));}}
看了大神的O(n)解法,不由得服。

vector<int> twoSum(vector<int>& numbers, int target) {    int lo=0, hi=numbers.size()-1;    while (numbers[lo]+numbers[hi]!=target){        if (numbers[lo]+numbers[hi]<target){            lo++;        } else {            hi--;        }    }    return vector<int>({lo+1,hi+1});}
另外,还有一种思路,虽然时间复杂度不如O(n),但是二分的思路也很值得学习。

I know that the best solution is using two pointers like what is done in the previous solution sharing. However, I see the tag contains "binary search". I do not know if I misunderstand but is binary search a less efficient way for this problem.

Say, fix the first element A[0] and do binary search on the remaining n-1 elements. If cannot find any element which equals target-A[0], Try A[1]. That is, fix A[1] and do binary search on A[2]~A[n-1]. Continue this process until we have the last two elements A[n-2] and A[n-1].

Does this gives a time complexity lg(n-1) + lg(n-2) + ... + lg(1) ~ O(lg(n!)) ~ O(nlgn). So it is less efficient than the O(n) solution. 

vector<int> twoSum(vector<int> &numbers, int target) {    if(numbers.empty()) return {};    for(int i=0; i<numbers.size()-1; i++) {        int start=i+1, end=numbers.size()-1, gap=target-numbers[i];        while(start <= end) {            int m = (start+end)/2;            if(numbers[m] == gap) return {i+1,m+1};            else if(numbers[m] > gap) end=m-1;            else start=m+1;        }    }}