Two Sum II - Input array is sorted

13 篇文章 0 订阅

题目地址:https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/

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

本想着这个题目难度不大,没想到做了一下,又死在了超时这个鬼界限上。

双层循环,既然有效,如果两个循环变量对应的数组元素的加和小于target,那么继续循环,如果等于,那么返回,如果大于,重新遍历。

public class TwoSumInputArrayIsSorted {
    public static int[] twoSum(int[] numbers, int target) {
        if (numbers.length <= 1)
            return new int[0];

        int index1 = 0;
        int index2 = 1;
        if (numbers[index1] + numbers[index2] > target)
            return new int[0];

        boolean breakloop = false;

        for (index1 = 0; index1 < numbers.length; index1++) {
            for (index2 = index1 + 1; index2 < numbers.length; index2++) {
                if (numbers[index1] + numbers[index2] < target)
                    continue;
                else if (numbers[index1] + numbers[index2] == target) {
                    breakloop = true;
                    break;
                } else
                    break;
            }
            if (breakloop == true)
                break;
        }

        return new int[]{index1 + 1, index2 + 1};
    }

    public static void main(String[] args) {
        int[] nums = {2, 3, 4};
        int[] res = twoSum(nums, 6);
        return;
    }
}

时间复杂度为 O(n2) ,如果数据量比较大的时候,那不行了。

既然有序,那我们在上面想法的基础上试试二分查询看看行不:

public class TwoSumInputArrayIsSorted {
    public static int[] twoSum(int[] numbers, int target) {
        if (numbers.length <= 1)
            return new int[0];

        int index1 = 0;
        int index2 = 1;
        if (numbers[index1] + numbers[index2] > target)
            return new int[0];

        for (int i = 0; i < numbers.length; i++) {
            int index = binarySearch(numbers, 0, numbers.length - 1, target - numbers[i]);
            if (i != index) {
                if ( i < index)
                    return new int[]{i + 1, index + 1};
                else
                    return new int[]{index + 1, i + 1};
            }
        }

        return new int[]{index1 + 1, index2 + 1};
    }

    public static int binarySearch(int[] nums, int low, int high, int target){
        if (low == high && nums[low] != target)
            return -1;

        int mid = low + high / 2;

        if (target == nums[mid])
            return mid;
        else if (target < nums[mid])
            return binarySearch(nums, low, mid - 1, target);
        else
            return binarySearch(nums, mid + 1, high, target);
    }

    public static void main(String[] args) {
        int[] nums = {2, 3, 4};
        int[] res = twoSum(nums, 6);
        return;
    }
}

这么搞会报栈溢出的错误。因为上面代码的二分查找用的是递归,所以可能是递归太深,那么把递归换成非递归又怎样?

public static int binarySearch(int[] nums, int low, int high, int target){
    while (low < high) {
        int mid = low + high / 2;
        if (target < nums[mid])
            high = mid - 1;
        else if (nums[mid] == target)
            return mid;
        else
            low = mid + 1;
    }
    if (low == high && target == nums[low])
        return low;
    return -1;
}

还是超时,啥也别说了。彻底换方法吧,我们能否遍历数组一次,就能找到答案,当然可以,假设两个指针分别指向数组的首位元素,两个元素和大于target了,尾部指针往前调整,两个元素和小于target了,首部指针往后调整:

public class TwoSumInputArrayIsSorted {
    public static int[] twoSum(int[] numbers, int target) {
        if (numbers.length <= 1)
            return new int[0];

        int index1 = 0;
        int index2 = numbers.length - 1;
        while (index1 < index2) {
            if (numbers[index1] + numbers[index2] > target)
                index2--;
            else if (numbers[index1] + numbers[index2] == target)
                return new int[]{index1 + 1, index2 + 1};
            else
                index1++;
        }
        return new int[]{};
    }
}

这回就快多了,时间复杂度为:O(n)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值