寻找满足和为定值的两个数
来源:互联网 发布:2016年网络神曲 编辑:程序博客网 时间:2024/05/15 13:30
参考:http://blog.csdn.net/v_JULY_v/article/details/6419466
https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/02.03.md
上面是大牛,我现在也是对着他的博客系列一篇篇在学习
寻找满足和为定值的两个数
一、算法思想:
例如对于给定数组 {1、2、4、7、11、15} 和 sum = 15,要求我们找出数组中满足和为sum的一对数。在有序和无序情况下,处理起来有所分别。O(n2)暴搜我就不说了
1、排序+二分查找
我们可以穷举第一个数,那对于第二个数如何确定?可以通过排序后进行二分查找获得。这样的时间复杂度是O(nlogn) 空间复杂度是O(1)
vector<int> twoSum_v1(int a[], int n, int sum) { sort(a, a+n); vector<int> res; for(int i = 0; i < n; ++ i) { int x = sum - a[i]; int left = i + 1, right = n - 1, mid; while(left <= right) { mid = (left + right) / 2; if(a[mid] == x) break; else if(a[mid] < x) left = mid + 1; else right = mid - 1; } if(left <= right) { res.push_back(a[i]); res.push_back(a[mid]); break; } } return res; }
2、哈希表,这里用C++的unorder_map
同样循环每次确定第一个数a[i],然后利用hash表查找sum-a[i]是否在数组中。利用哈希表一个好处就是不用排序, 时间复杂度也降到了 O(n),但是需要 的空间复杂度O(n)
//unorder_map 哈希表实现 vector<int> twoSum_v2(int a[], int n, int sum) { unordered_map<int,bool> exist; vector<int> res; for(int i = 0; i < n; ++ i) exist[a[i]] = true; for(int i = 0; i < n; ++ i) { int x = sum - a[i]; if(exist.find(x) != exist.end()) { res.push_back(a[i]); res.push_back(x); break; } } return res; }
3、两个指针逼近法
OK,有没有更神奇的办法?利用两个指针一趟就能扫描所有的组合情况?有的,但是这种方法必须基于数组是有序的情况。在对数组排序后的情况下,一个头指针i,一个尾指针j,i只能向后移动,j只能向前移动。
- 如果a[i]+a[j]==sum 返回相应的两个数
- 如果a[i]+a[j]<sum 试图使求和变大些,则i向后移动一个试试(这里不能用j++,因为j+1的情况已经处理过了,要让两个指针遍历完所有的情况,j就只能往前,i只能往后,否则情况就太乱了,放心,这样子是一定能找到满足条件的值的,因为它能遍历完所有的情况)
- 如果a[i]+a[j]>sum 试图使求和变小些,则j向前移动
时间复杂度O(nlogn) 空间复杂度O(1)
//两个指针两端扫描实现 vector<int> twoSum_v3(int a[], int n, int sum) { vector<int> res; sort(a, a + n); int i = 0, j = n -1; while( i < j) { if(a[i] + a[j] == sum) { res.push_back(a[i]); res.push_back(a[j]); break; } else if(a[i] + a[j] < sum) { ++i; } else --j; } return res; }
二、若是要求我们返回下标,而不是具体数值呢?
个人觉得这时候如果数组本身有序,就利用思路三,两指针逼近法;若数组本身无序,则思路二,hasp表这时候最方便了。不可先排序后处理,这时候下标已经改变了,直接用上述方法得到的结果就不正确了。
- 寻找满足和为定值的两个数
- 寻找数组中满足和为定值的两个数或所有可能组合
- 寻找两个数的和为定值的算法
- 寻找和为定值的两个数
- 寻找和为定值的两个数
- 寻找和为定值的两个数
- 寻找和为定值的两个数/多个数
- 寻找和为定值的两个数
- 寻找和为定值的两个数
- 寻找和为定值的两个数
- 寻找和为定值的两个数
- 【算法】寻找和为定值的两个数
- 寻找和为定值的两个数
- 寻找和为定值的两个数
- 寻找和为定值的两个数
- 数组------寻找和为定值的两个数
- 寻找和为定值的两个数
- 寻找和为定值的两个数
- 伪中介模式(5.5)
- applicationContext.xml配置文件详解
- hdu 1412 {A} + {B}(集合合并)
- Static Initialization in C#
- 给想跨专业考研的同学:确定考研目标,立足自我进行安排
- 寻找满足和为定值的两个数
- 字符设备驱动
- Cocos2d-x 3.2创建项目与交叉编译生成APK
- java操作数据库的语句一个易错点
- [一问一答][Android] 如何在两个Activity之间传递(共享)数据
- 【FZU】2105 Digits Count 线段树
- STL algorithm算法rotate,rotate_copy(51)
- 20140925-Linux Bash严重漏洞修复紧急通知
- 程序员如可把握住自己那个奔向梦想的心