给一个整数数组,找到两个数使得他们的和等于一个给定的数 target。输出这两个数的下标, 并且第一个下标小于第二个下标。注意这里下标的范围是 0 到 n-1。你可以假设数组递增有序,O(N)时间完成

21 篇文章 0 订阅

描述

给一个整数数组,找到两个数使得他们的和等于一个给定的数 target。
你需要输出这两个数的下标, 并且第一个下标小于第二个下标。注意这里下标的范围是 0 到 n-1。
你可以假设数组递增有序。
请在O(N)时间内完成。

输入

第一行:N个整数,作为数组的元素,空格分开
第二行:target

输出

两个下标,空格隔开。如有多组满足要求,输出靠前的一组。

样例输入

4
2 7 11 15
9

样例输出

0 1

我们看到这个题首先想到的就是双重循环,如果是用双重循环做的话,这个题就非常简单了,但是题目要求要在O(N)时间内完成
我们先来看如果是双重循环我们该怎么写

O(N^2)

static int[] f(int[] arr,int k) {
		for (int i = 0; i < arr.length-1; i++) {
			for (int j = 1; j < arr.length; j++) {
				if(arr[i]+arr[j]==k) {
					return new int[] {i,j};
				}else {
					continue;
				}
			}
		}
		return new int[] {-1,-1};
	}

结果
结果
这个做可以非常简单的解决两个数,但是时间复杂度在O(N^2)

其实实际上我们可以这样想

要在O(N)时间内完成就要说只能用一个循环
假设k是我们要的结果,在数组中找两个下标

k - Arr[i] = result //是不是我们只需要在数组中找到result这个值就好了

考虑如果有重复例如:8 - 4 = 4 那么我们要找是另一个4而不是我们减的这个4
总结以上:要在数组排除减去的值,在剩下的值中找我们要的结果

代码实现
//O(N)

	static int[] f1(int[] arr,int k) {
		for (int i = 0; i < arr.length; i++) {
			int c = k - arr[i];
			int index = binarySearch(arr, 0, arr.length-1, c);//在这里我们调用了一个二分查找
			if(index != -1 && index != i) {//找到了,而且不是我们减的那个值
				return new int[] {i,index};
			}
		}
		return new int[] {-1,-1};
	}

我在这里调用的是个二分寻找O(lg2N),调用顺序O(N)

//二分查找
static int binarySearch(int[] arr,int begin,int end,int k) {
		if (begin>end) return -1;//前后指针交叉就是没找到
		int indexMid = (begin+end)>>1;//偶数减一半,奇数减一半+1
		int Val = arr[indexMid];
		if(Val > k)
			return binarySearch(arr, begin, indexMId-1, k);
		else if(Val < k)
			return binarySearch(arr, indexMid+1, end, k);
		return indexMid;
	}

利用 差的方式 这个题有 排序、查找 的基础就可以很简单的解题

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值