LeetCode:Two Sum II - Input array is sorted

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/vivianXuejun/article/details/79208208

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.

Example:

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

我的解法:

public class AlgorithmTest2 {

    public static void main(String[] args) {
        //给定一组排好序(递增)的数组
        int[] nums = {2,4};
        int target = 6;
        int[] results = twoSum(nums, target);
        System.out.println(results[0]+"  " + results[1]);
    }

    public static int[] twoSum(int[] numbers, int target) {
        int left = numbers[0];
        int right = numbers[numbers.length-1];
        int middle = numbers[numbers.length/2];
        for(int k=0; k<numbers.length; k++){
            int cursor = target - numbers[k];
            if(cursor <= middle){
                for(int i=0; i<numbers.length/2+1; i++){
                    //注意两个下标不能相等(i!=k),避免重复(例如出现这样的数组:[0,0,3,4])
                    if(cursor == numbers[i] && i!=k) {
                        if(k < i){
                            return new int[]{k+1, i+1};
                        } 
                        return new int[]{i+1, k+1};
                    }
                }
            }else if(cursor > middle){
                for(int i=numbers.length-1; i>=numbers.length/2; i--){
                    if(cursor == numbers[i] && i!=k){
                        if(k < i){
                            return new int[]{k+1, i+1};
                        } 
                        return new int[]{i+1, k+1};
                    }
                }
            }
        }

        return null;
    }
}

我的做法在LeetCode上并不能通过,因为时间复杂度太大了为O(n^2).因此我查看网上的博客:https://segmentfault.com/a/1190000006697526:这是用二分查找+双指针做的:

public class Two_Sum_II {
    public int[] twoSum(int[] numbers, int target) {
        int[] result = new int[2];
        //这里用二分搜索,我常用startend来命名两头,middle是中间。
        int start = 0;
        int end = numbers.length-1;
        //这个while循环条件很巧妙,二分搜索建议固定一个模板,这个就挺好固定的。
        while (start + 1 < end) {
            //看,我刚说的是实话,而且这里middle的计算方法是防止越界。
            int middle = start + (end-start)/2;
            if (numbers[start] + numbers[end] < target) {
                //这里需要判断,到底是跳一半还是走一步,就再加个判断。
                if (numbers[middle] + numbers[end] < target) {
                    start = middle;
                }
                else {
                    start++;
                }
            }
            else if(numbers[start] + numbers[end] > target) {
                if (numbers[middle] + numbers[start] > target) {
                    end = middle;
                }
                else {
                    end--;
                }
            }
            else {
                break;
            }
        }
        //题目中保证了有结果,还不是zero-based,那么就把result两项都续一秒。
        result[0] = start+1;
        result[1] = end+1;
        return result;
    }
}

其时间复杂度:

当然就是最坏情况O(n)了,也是标准的双指针复杂度。不过二分搜索方法是它最优情况是O(nlgn)。

另附博客:https://www.cnblogs.com/grandyang/p/5185815.html
中提到一个双指针的情况:

我们只需要两个指针,一个指向开头,一个指向末尾,然后向中间遍历,如果指向的两个数相加正好等于target的话,直接返回两个指针的位置即可,若小于target,左指针右移一位,若大于target,右指针左移一位,以此类推直至两个指针相遇停止,参见代码如下(c++):

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int l = 0, r = numbers.size() - 1;
        while (l < r) {
            int sum = numbers[l] + numbers[r];
            if (sum == target) return {l + 1, r + 1};
            else if (sum < target) ++l;
            else --r;
        }
        return {};
    }
};

将其转为java语言:

public static int[] twoSum2(int[] numbers, int target) {
        int start = 0;
        int end = numbers.length-1;

        while(start < end){
            if(numbers[start]+numbers[end] == target){
                return new int[]{start+1, end+1};
            }else if(numbers[start]+numbers[end] < target){
                start++;
            }else{
                end--;
            }
        }

        return null;
    }

猜你喜欢

转载自blog.csdn.net/vivianXuejun/article/details/79208208