首页 > 代码库 > 寻找和为定值的两个数
寻找和为定值的两个数
寻找和为定值的两个数
1. 题目描述
给定一个数组(无序或者有序,两种情况都要考虑),找出和为M的两个数。最多时间复杂度能有多少?
https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/02.02.md
2. 数组有序——两端指针扫描法
数组有序的情况,在时间复杂度上我们就省去了排序的O(NlogN)。
我们使用两端指针扫描法是比较简单的,时间复杂度为O(N), 空间复杂度为O(1)。如下图所示:
首先我们在数组两端分别放上一个标志:head, tail。
然后,判断它们指向的值之和sum是否等于M,
如果sum==M, 记录结果!head, tail同时往中间移动一次;
如果sum<M, tail往中间移动一次;
如果sum>M, head往中间移动。
直到,head>tail,返回结果~
总共的时间复杂度就是很厉害的O(N), 空间复杂度也只是O(1)。但是注意前提是数组要有序~
程序如下:
#include<iostream> using namespace std; void FindTwo(int *a, int M, int num) { int head=0, tail=num-1; while(head<tail) { int sum=a[head]+a[tail]; if(sum==M) { cout<<a[head]<<'\t'<<a[tail]<<endl; head++; tail--; continue; } if(sum>M) { tail--; continue; } if(sum<M) { head++; continue; } } } int main() { int a[10]={2,3,6,8,9,11,14}; //int a[10]={2,3,6,8,9,11,14}; int M=15; int num=7; FindTwo(a, M, num); return 0; }
3. 数组无序——映射hash表或者数组
当数组无序的时候,当时我们可以先排序, 然后再使用上面的方法。这是时间复杂度为O(NlogN),空间复杂度为O(1)。
或者我们还可以使用映射hash表或者数组,详细来说:
把数组M - a[i]映射到一个hash表或者是一个数组,然后我们就判断原数组和数组M - a[i]时候有元素相等,如果则返回结果。判断相等的方法我们也可以使用两端夹逼方法。
这种方法的时间复杂度为O(N), 空间复杂度为O(N)。
ps:其实在无序的情况,还是映射到hash表比较好,映射到数组也不是很好操作~
寻找和为定值的两个数