谷歌面试题:输入是两个整数数组,他们任意两个数的和又可以组成一个数组,求这个和中前k个数怎么做?
来源:互联网 发布:自动成语接龙软件 编辑:程序博客网 时间:2024/04/25 09:54
分析:
“假设两个整数数组为A和B,各有N个元素,任意两个数的和组成的数组C有N^2个元素。 那么可以把这些和看成N个有序数列: A[1]+B[1] <= A[1]+B[2] <= A[1]+B[3] <=… A[2]+B[1] <= A[2]+B[2] <= A[2]+B[3] <=… … A[N]+B[1] <= A[N]+B[2] <= A[N]+B[3] <=… 问题转变成,在这N^2个有序数列里,找到前k小的元素”
在网上看到相关分析,就如上面的分析所述:A[i1] + B[j1] 和A[i2] + B[j2],在i1和i2,j1和j2这四个数不一样的情况下,根本无法确定谁大谁小,比如A[3] + B[0]和A[1] + B[1],所以单纯地比较A中的i1和i2或者B中的j1和j2都是会有问题的。我想这个题的思路可以是:1、在A中选k个最小值,并排序(升序)
2、在B中选k个最小值,并排序(升序)
3、再在这些数中,进行相关操作。
部分代码如下:
#include<iostream>#include<vector>#include<algorithm>using namespace std;typedef struct sum_info{int value;int i;int j;}sum_info;bool cmp(sum_info a,sum_info b){return a.value < b.value;}//判断ai,bj这两个数的和有没有必要加入q这个容器里,如果ai的下标和bj的下标在q中已经有比他们小的加和存在了那么就没有必要了bool IsBig(vector<sum_info> q, int ai, int bj){for(int i = 0; i < q.size(); i++){sum_info tmp = q.at(i);if(tmp.i <= ai && tmp.j <= bj)return true;}return false;}int *min_k(int *A,int *B,int k, int length){if(A==NULL||B==NULL||k<=0)return NULL;vector<sum_info> q;//利用C++的STL,其中存放的是目前为止备选的最小和sum_info tmp;tmp.value=A[0]+B[0];tmp.i=0;tmp.j=0;q.push_back(tmp);//起始时,只有A[0]+B[0]int *result=new int[k];//存储结果的数据int count,i,j;count=0;//计数用while(count<k){tmp=q.at(0);//取出第一个元素q.erase(q.begin());result[count++]=tmp.value;i=tmp.i;j=tmp.j;//接下来的操作是关键,就是看是否将a[i+1]+b[j] 和 a[i]+b[j+1]加入到q中,这里就需要遍历q了sum_info a,b;if((i+1)<length && !IsBig(q,i+1,j)){a.i=i+1;a.j=j;a.value=A[i+1]+B[j];q.push_back(a);}if((j+1)<length && !IsBig(q,i,j+1)){b.i=i;b.j=j+1;b.value=A[i]+B[j+1];q.push_back(b);}sort(q.begin(),q.end(),cmp);}return result;}int main(){int A[]={2, 8, 9, 15};int B[]={1, 9, 11, 12};int *result=min_k(A,B,16,4);if(result!=NULL){for(int i=0;i<16;i++)cout<<result[i]<<" ";cout<<endl;delete []result;}return 0;}这个代码的重点,就是保持原有的在取了A[i]+B[j]的和之后,再选择A[i+1]+B[j]和A[i]+B[j+1],但是不能简简单单选择,需要进行一定的判断。 其实可以在纸上画一画自己如果计算时,所用的思路。然后就能在程序中进行刻画了。
0 0
- 谷歌面试题:输入是两个整数数组,他们任意两个数的和又可以组成一个数组,求这个和中前k个数怎么做?
- 谷歌面试题:输入是两个整数数组,他们任意两个数的和又可以组成一个数组,求这个和中前k个数怎么做?
- 输入一个递增的数组和一个数字s,找出数组中任意两个数使他们的和正好是这个数字s,如果有任意多对数字的和为s,输出任意一堆数字即可,例如,输入数组[1,2,4,7,11,15]和数字
- ms 两个数组,从每个数组中取一个数相加,求最大的前k个和
- 输入一个递增排序的数组和一个数字sum,在数组中查找两个数,使得他们的和正好是sum
- 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
- 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的
- 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
- 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
- 输入一个按照升序排列的数组和一个数字,在数组中查找两个数,使得他们的和正好是输入的那个数字,要求时间复杂度是O(n),如果有多对数字的和等于输入的数字,输入任意一对即可。
- 输入一个升序数组和一个整数,在数组里面找两个数使它们相加的和为这个整数
- 一个N个整数的无序数组,给你一个数sum,求出数组中是否存在两个数,使他们的和为sum
- 一个N个整数的无序数组,给你一个数sum,求出数组中是否存在两个数,使他们的和为sum
- 输入两个整数,求他们和差商积
- 在数组中求出两个数,使他们的和等于给定的一个数
- 输入两个整数,求他们的和差积商和余数
- 给一个整数数组,找到两个数使得他们的和等于一个给定的数 target(容易)
- 求一个数组中的和为任意一个数的两个元素
- cocos2d-x屏幕适配原理分析
- nyoj814 又见拦截导弹 贪心
- Java Servlet学习笔记(一)初识servlet
- 学习计划
- 选择排序
- 谷歌面试题:输入是两个整数数组,他们任意两个数的和又可以组成一个数组,求这个和中前k个数怎么做?
- 对话框的收缩和扩展
- 麻将遥控器
- wpa_supplicant log 输出控制
- Gitlab7.8.x 配置邮件功能
- Android通过get方法访问Tomcat服务器,发送账号密码,检测登陆是否成功。
- FFmpeg的H.264解码器源代码简单分析:解码器主干部分
- 卡特兰数
- 控件关联成员变量