您的位置:首页 > 其它

从数组中找出其和等于S的两个数

2017-01-12 12:06 274 查看
在一个正数数组A[]中,看是否存在两个数,要求这两个数之和等于某个指定的数S。

当然,解法有很多种。

我就把我想到的,以及别人提供的一些思路总结一下。反正大概都是头脑风暴了。

1.  最朴实的做法

两重for循环。就算只算一个矩阵的下三角,那也是O(n^2)的量级。

2. 排序以后再找

因为是数组中全是正数,把S分解成两个整数相加,最大也就是S-1了。所以,如果能将数组A[]是个有序数组,就能很快将搜索范围缩小。于是我想了以下办法。

(1) 基数排序。O(dn)。d是关键字的位数。.e.g. 127的位数是3。

(2) 排序以后,二分查找到S的位置M。搜索范围降到了A[0] - A[M-1]。log2(n)。

(3) 再用第1种方法,O(M^2)。

3. 借助set

如果不排序,从左往右扫描A[],用set。

(1) i=0。遇到第一个数A[i],就把S-A[i]放入set。i++。

(2) 遇到第二个数A[i],就去看set中是否有A[i]。若有,就结束;若没有,就把S-A[i]继续放入set。i继续++。

(3) 重复上述过程。

据说STL的set是用红黑树实现的,查找、插入、删除等操作的时间复杂度为O(log2n)。

那么,这样做的复杂度,会是多少呢?

4. 那hashmap呢?

据说STL的map也是用红黑树实现的。hashmap是用哈希表实现的。

那么C++的hashmap怎么写?各种操作的复杂度大概是多少呢?

map和hashmap的区别呢?如果有碰撞,冲突怎么解决呢?所需时间呢?

5. 找到S的位置,把小于S的都放在S的左边

这个做法就类似于“如何从N个乱序数据中,快速地找出第K小的数?”了。

Review:快速找出第K小的数

先累计比S小的一共有多少个数,假设是M个,然后通过快排的找法,很快就能把范围缩小至M个了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 头脑风暴