从数组中找出其和等于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个了。
当然,解法有很多种。
我就把我想到的,以及别人提供的一些思路总结一下。反正大概都是头脑风暴了。
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个了。
相关文章推荐
- 浅析时钟向量算法
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- C#算法函数:获取一个字符串中的最大长度的数字
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- 经典排序算法之冒泡排序(Bubble sort)代码
- Android数据加密之异或加密算法的实现方法
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法