剑指Offer 两数之和 - 输入有序数组

题目链接

剑指Offer 两数之和 - 输入有序数组

思路

思路一 暴力

两层循环,外层循环固定一个值(value),内层循环寻找是否存在target-value,若存在就返回

public int[] twoSum(int[] numbers,int target){
	int[] res = new int[2];
	for(int i=0;i<numbers.length;i++){
		int value = numbers[i];
		for(int j=i+1;j<numbers.length;j++){
			if(numbers[j] == target - value){
				res[0] = i;
				res[1] = j;
				return res;
			}
		}
	}
	return res;
}

时间复杂度:O( N 2 N^2 N2)
空间复杂度:O(N)

思路二 循环+二分

即外层循环固定一个值,内层用二分查找在数组中查找target-value

int binarySearch(int[] nums,int start,int target){
        int i = start,j = nums.length-1;
        while (i<=j){
            int mid = (i+j)/2;
            if(nums[mid] == target)
                return mid;
            else if(nums[mid] > target){
                j--;
            }else
                i++;
        }
        return -1;
}
public int[] twoSum(int[] nums,int target){
	int[] res = new int[2];
	for(int i=0;i<nums.length;i++){
		int value = nums[i];
		int index = binarySearch(nums,i+1,target-value);
		if(index!=-1){
			return new int[]{i,index};
		}
	}
	return res;
}

时间复杂度:O(Nlogn)
空间复杂度:O(N)

思路三 双指针

这个思路我没有想出来

双指针的本质是缩小搜索空间

别人的想法:别人的想法
题目中的解空间是 i , j ∣ 0 < = i < n , 0 < = j < = n {i,j}|0<=i<n,0<=j<=n i,j∣0<=i<n,0<=j<=n
搜索空间如下是白色的倒三角部分,因为题目要求i<j

在这里插入图片描述

初始状态,i=0,j=n
在这里插入图片描述

对于nums[0]+nums[7]与target的大小关系,要么大于,要么小于,要么等于,等于直接就返回就行。下面来分析小于的情况
由于nums[0]+nums[7]<target,我们需要找更大的两个数字,但nums[7]已经是最大的了,所以只能对i进行操作,那么是+1还是-1?
考虑+1的可能性
nums[0] + nums[7]<target
那么nums[0]+nums[7]<nums[1]+nums[7]<=target
因为是升序的
考虑-1的可能性
nums[i] + nums[j] < target
那么nums[i-1]+nums[j]<nums[i]+nums[j]<target
所以在和小于target的情况下,只可能对i+1

考虑大于的时候
nums[0]+nums[7]>target
我们需要找小于的情况,你不可能将nums[0]换成nums[1],因为nums[1]+nums[7]>target
所以只可能更改nums[7],让nums[7]换成nums[6]

所以代码如下

class Solution {
    public int[] twoSum(int[] numbers, int target) {
                int[] res = new int[2];
        int i = 0,j=numbers.length-1;
        while (i<j){
            int sum = numbers[i] + numbers[j];
            if(sum==target){
                res = new int[]{i+1,j+1};
                return res;
            }
            else if(sum>target){
                j--;
            }else if(sum<target){
                i++;
            }
        }
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值