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

在一个正数数组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个了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qcyfred

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值