编程之法section II: 2.2 和为定值的两个数
数组篇
2.2 求和为定值的两个数:
题目描述:有n个整数,找出其中满足两数相加为target的两个数(如果有多组满足,只需要找出其中一组),要求时间复杂度尽可能低。
解法一:
思路:开散列映射,空间换时间, 查找耗时o(n)
Writer: zzq
Function: 求和为定值的两个数。
方法一: 开散列映射(哈希表)。
1) 用哈希表Hashmap先把数组中的数字和对应的下标进行存储,(键,值)=(具体数值,对应下标);
2) 遍历数组,对loss=target-nums[i],在Hashmap中找是否存在loss,找到即返回loss所对应的value,也就是所对应的数组下标;
时间复杂度:O(n)
#include<iostream>
#include<map>
using namespace std;
//哈希表存储查找
void twoSum(int *nums, int *result, int length, int target) {
map<int, int> hashmap;
for (int i = 0; i < length; i++)
hashmap[nums[i]]=i;
map<int, int>::iterator it;
for (int i = 0; i < length; i++) {
int v = target - nums[i];
it = hashmap.find(v);
if(it!=hashmap.end() && i != it->second){
result[0] = i;
result[1] = hashmap[v];
break;
}
}
}
int main(){
int nums[]={10,12,8,56,98,43,21,15,76,19};
int target = 20;
int result[2] = {0,0};
twoSum(nums, result,10, target);
cout<<result[0]<<' '<<result[1]<<endl;
return 0;
}
解法二:
思路:快排O(logn)+二分法O(nlogn).
Writer: zzq
Function: 求和为定值的两个数。
方法二: 1)先对给定数组进行排序;
2)在排序好的数组基础上,每次对于loss=target-nums[i],是用二分法查找loss是否存在,如果存在,则返回这两个数;
时间复杂度:O(logn)+O(nlogn),
【 排序:O(logn);
二分查找: O(nlogn)。
】
#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
// 快速排序
void QuickSort(int *a, int begin, int end){
if(begin<end){
int i = begin;
int j = end;
int temp = *(a+i);
while(i<j){
while(i<j&&*(a+j)>=temp)j--;
if(i<j){
*(a+i)=*(a+j);
i++;
}
while(i<j&&*(a+i)<=temp)i++;
if(i<j){
*(a+j)=*(a+i);
j--;
}
}
*(a+i)=temp;
QuickSort(a,begin,i-1);
QuickSort(a,i+1,end);
}
}
//二分查找
int BinaryQuery(int *a,int goal,int start, int end){
int i=start,j=end;
int flag = 0;
while(i<=j){
int middle = (j-i)/2;
if(goal==*(a+middle)){
return 1; // 找到目标值
}
else if(goal<*(a+middle)){ // 目标值在左半部分
j = middle-1; // 尾下标指向左半部分最后一个元素
}
else{ // 目标值在右半部分
i = middle +1; // 首指针指向右半部分最后一个元素
}
}
return 0;
}
int main(){
int n,sum;
cin>>n>>sum;
int a[n];
int i;
for(i = 0;i<n;i++)cin>>a[i];
QuickSort(a,0,n-1); // 快排
for(i = 0;i < n;i++){
if((sum-a[i])>0){
int flag = BinaryQuery(a,sum-a[i],0, n-1);
if(flag){
cout<<a[i]<<' '<<sum-a[i]<<endl;
break;
}
}
}
return 0;
}
解法三:
思路:快排O(logn)+ two pointers [首尾指针法]O(n).
Writer: zzq
Function: 求和为定值的两个数。
方法二: 1)先对给定数组进行排序;
2)在排序好的数组基础上,每次对于loss=target-nums[i],是用首尾指针法查找loss是否存在,如果存在,则返回这两个数;
时间复杂度:O(logn)+O(nlogn),
【 排序:O(logn);
two pointers: O(n)。
】
#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
// 快速排序
void QuickSort(int *a, int begin, int end){
if(begin<end){
int i = begin;
int j = end;
int temp = *(a+i);
while(i<j){
while(i<j&&*(a+j)>=temp)j--;
if(i<j){
*(a+i)=*(a+j);
i++;
}
while(i<j&&*(a+i)<=temp)i++;
if(i<j){
*(a+j)=*(a+i);
j--;
}
}
*(a+i)=temp;
QuickSort(a,begin,i-1);
QuickSort(a,i+1,end);
}
}
// 首尾指针法
void GetGoalIndex(int *a, int goal,int start,int end){
int begin = start;
int last = end;
while(begin<=last){
int currentSum = *(a+begin)+*(a+last);
if(currentSum==goal){
cout<<*(a+begin)<<' '<<*(a+last);
// 如果需要找到所有满足条件的对数,则需要加上这两行
//begin++;
//last--;
break;
}
else{
if (currentSum>goal){
last--;
}
else{
begin++;
}
}
}
}
int main(){
int n,sum;
cin>>n>>sum;
int a[n];
int i;
for(i = 0;i<n;i++)cin>>a[i];
QuickSort(a,0,n-1); // 快排
GetGoalIndex(a,sum,0, n-1);
return 0;
}
举一反三:
找和为定值的两个数的下标,并且两个数不能是同一个。
1:散列表法
2:快排+two pointers(新建数组b跟踪存储下标变化情况)。
void QuickSort(int *a, int *b, int begin, int end){
//cout<<begin<<' '<<end<<endl;
if(begin<end){
int i = begin;
int j = end;
int temp = *(a+i);
int temp_index=*(b+i);
while(i<j){
while(i<j&&*(a+j)>=temp)j--;
if(i<j){
*(a+i)=*(a+j);
*(b+i)=*(b+j);
i++;
}
while(i<j&&*(a+i)<=temp)i++;
if(i<j){
*(a+j)=*(a+i);
*(b+j)=*(b+i);
j--;
}
}
*(a+i)=temp;
*(b+i)=temp_index;
//for(int i=0;i<10;i++)cout<<b[i]<<' ';
//cout<<endl;
QuickSort(a, b, begin, i-1);
QuickSort(a, b, i+1, end);
}
}
// 寻找下标 ,用数组c接收下标
void GetGoalIndex(int *a, int *b, int *c, int goal,int start,int end){
int begin = start;
int last = end;
while(begin<=last){
int currentSum = *(a+begin)+*(a+last);
if(currentSum==goal){
if(*(b+begin)>*(b+last)){
*c=*(b+last);
*(c+1)=*(b+begin);
}
else{
*c=*(b+begin);
*(c+1)=*(b+last);
}
break;
}
else{
if (currentSum>goal){
last--;
}
else{
begin++;
}
}
}
}
int* twoSum(int* nums, int numsSize, int target) {
int i;
int b[numsSize];
static int c[2];
for(i = 0;i<numsSize;i++){
b[i]=i;
}
QuickSort(nums, b, 0, numsSize-1);
//for(int i=0;i<10;i++)cout<<b[i]<<' ';
//cout<<endl;
GetGoalIndex(nums, b, c,target, 0, numsSize-1);
return c;
}
编程之法section II: 2.2 和为定值的两个数的更多相关文章
- 编程之法section II: 2.1 求最小的k个数
====数组篇==== 2.1 求最小的k个数: 题目描述:有n个整数,请找出其中最小的k个数,要求时间复杂度尽可能低. 解法一: 思路:快排后输出前k个元素,O(nlogn). writer: zz ...
- 编程之法:面试和算法心得(寻找最小的k个数)
内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 输入n个整数,输出其中最小的k个. 分析与解法 解法一 要求一个序列中最小的k个数,按照惯有的思维方式,则是先对这个 ...
- 编程之法:面试和算法心得(字符串包含java实现)
内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 给定两个分别由字母组成的字符串A和字符串B,字符串B的长度比字符串A短.请问,如何最快地判断字符串B中所有字母是否都 ...
- 编程之法:面试和算法心得(旋转字符串java实现)
内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 给定一个字符串,要求把字符串前面的若干个字符移动到字符串的尾部,如把字符串“abcdef”前面的2个字符'a'和'b ...
- 老雷socket编程之websocket实现
老雷socket编程之websocket实现 我们主要实现私聊和群聊两个功能,要在web端实现想微信QQ那样的即时通讯的功能,我们需要了解一下websocket.websocket是一种可以双向通讯的 ...
- Java并发编程之CAS第三篇-CAS的缺点及解决办法
Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...
- C++混合编程之idlcpp教程Lua篇(7)
上一篇在这 C++混合编程之idlcpp教程Lua篇(6) 第一篇在这 C++混合编程之idlcpp教程(一) 与LuaTutorial4工程相似,工程LuaTutorial5中,同样加入了四个文件: ...
- shell编程之awk命令详解
shell编程之awk命令详解 a:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; out ...
- 并发编程之:ThreadLocal
大家好,我是小黑,一个在互联网苟且偷生的农民工. 从前上一期[并发编程之:synchronized] 我们学到要保证在并发情况下对于共享资源的安全访问,就需要用到锁. 但是,加锁通常情况下会让运行效率 ...
随机推荐
- 在线预览word
# eg http://view.officeapps.live.com/op/view.aspx?src=<Document Location> #demo <a hr ...
- Mac配置虚拟主机
一.启动Apache 终端输入:sudo apachectl start Apache的安装目录在:/etc/apache2/,etc默认是隐藏的.有三种方式查看: 1.桌面位于Finder时:shi ...
- MySQL数据表命令
显示表的相关信息: show table status like "表名": show table status like "表名" \G 格式化, ...
- C语言入门教程-(5)格式化输入输出
1.输入和输出 在程序的使用中,我们经常可以看的这么一个场景:用户需要输入数据,经过程序运算,得到结果后输出.在C语言中,输入数据和输出数据都是由库函数完成的,通过语句来输入/输出. 2.格式化输出— ...
- SEO优化上首页之搜索引擎作弊案例与反作弊原理
搜索引擎流量价值巨大,有不少人专门研究排名机制,利用搜索引擎漏洞作弊,寻求快速提高网站排名,进而获取更多的流量和利益,甚至有的网站优化公司专门提供作弊服务.搜索引擎为了杜绝这种情况,必须能过滤大量垃圾 ...
- 柯朗微积分与数学分析习题选解(1.2 节 d)
一直在读<陶哲轩实分析>,陶的书非常的严谨,环环相扣,但是也有个缺点就是计算性的例子和应用方面的例子太少了.所以就又找了本柯朗的<微积分与数学分析>搭配着看.柯朗的书的习题与陶 ...
- 【RedHat Linux】 链路聚合
[链路聚合] RHEL 7运行模式:teamd 守护进程, teamdctlroundrobin 轮询activebackup 热备份, 其中一个位为backuploadbalance 负载均衡lac ...
- 5285: [Hnoi2018]寻宝游戏
5285: [Hnoi2018]寻宝游戏 链接 分析: 从下面依次确定运算符号,然后在确定的过程中,需要确定的位数会逐渐减少.比如最后有一个1,如果在从下往上确定了一个or 1,那么再往前可以随便选了 ...
- DELL R710使用4T硬盘亮黄灯
事件背景 公司DELL R710的物理机上面运行的SQL SERVER数据库,因存储空间不足需要扩充空间.现系统盘(300G SAS 6Gbps 15K*2)RAID 1,数据盘(500G SAS 6 ...
- Maven+spring+springMVC+mybatis+Junit+Log4j配置个人总结
首先粘贴上项目引用地址:http://doc.okbase.net/fengshizty/archive/126397.html 这里对创建步骤不做过多解释,只是针对案例创建demo的一些 ...