标签:题目 clu odi namespace lob 有序 扫描法 ons hashtable
给定一个数组(无序或者有序,两种情况都要考虑),找出和为M的两个数。最多时间复杂度能有多少?
https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/02.02.md
数组有序的情况,在时间复杂度上我们就省去了排序的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)。但是注意前提是数组要有序~
程序如下:
当数组无序的时候,当时我们可以先排序, 然后再使用上面的方法。这是时间复杂度为O(NlogN),空间复杂度为O(1)。
或者我们还可以使用映射hash表或者数组,详细来说:
把数组M - a[i]映射到一个hash表或者是一个数组,然后我们就判断原数组和数组M - a[i]时候有元素相等,如果则返回结果。判断相等的方法我们也可以使用两端夹逼方法。
这种方法的时间复杂度为O(N), 空间复杂度为O(N)。
ps:其实在无序的情况,还是映射到hash表比较好,映射到数组也不是很好操作~
#include <iostream> using namespace std; const int size=100; int main() { int hashtable[size]; for(int i=0;i<size;i++) hashtable[i]=0; int a[size]={1,2,4,5,7,11,15}; for(int i=0;i<7;i++) hashtable[a[i]]=1; int sum=15; for(int i=0;i<7;i++) if(hashtable[i]&&hashtable[sum-i]) cout<<"这两个数为"<<i<<" "<<sum-i<<endl; else cout<<"不存在这样的两个数."<<endl; return 0; }
标签:题目 clu odi namespace lob 有序 扫描法 ons hashtable
原文地址:http://www.cnblogs.com/wft1990/p/7028676.html