人人校招笔试题
来源:互联网 发布:人工智能对世界的影响 编辑:程序博客网 时间:2024/06/11 01:02
人人校招笔试题
---9月22日,人人校招笔试题
1、给定一个有序数组a,长度为len,和一个数X,判断A数组里面是否存在两个数,他们的和为X,bool judge(int *a, int len, int x),存在返回true,不存在返回false
2、给定有n个数的数组a,其中超过一半的数为一个定值,在不进行排序、不开设额外数组的情况下,以最高效的算法找到这个数:int find(int *a, int n)
题解:(转载请联系博主,个人看法,仅供参考!)
1、给定一个有序数组a,长度为len,和一个数X,判断A数组里面是否存在两个数,他们的和为X,bool judge(int *a, int len, int x),存在返回true,不存在返回false
解: 注意仔细研究题目中的条件,比如关键的一句,有序数组a,这是一个有序的数组,这一点十分重要!
思路1:遍历,时间复杂度为O(N2),很显然,这种方法没什么实际意义,而且题目中说了这个一个有序数组,采用遍历的方法是你想不出其他解法时的最坏选择而已!
思路2:根据有序数组的特点,要么递增要么递减,这个时候我们不要凭空想象,拿出纸和笔,举一个实例来分析是最好的方法,
算法的思路通过上图可以清晰的表现出来,这里再简单叙述一下:申请一个与原数组a[N]一样长度的内存空间arr[N],用给定的值X减去原数组中的元素,对应的放到申请的内存空间arr[N]中,设置两个指针p和q,分别指向原数组a[N]的最后一个元素和arr[N]的第一个元素,指针移动满足条件:
指针移动必须满足条件:p和q指针没有越界,越界则跳出
若指针指向的值相等且i不等于j(添加了条件:i不等于j,避免出现8 = 4 + 4的情况),则返回true;
若原数组是升序的,那么每次移动指向的值较大的指针;
若原数组是降序的,那么每次移动指向的值较小的指针;
移动结束,跳出移动指针的循环,说明不存在,返回false
这道题目其实可以不用那么复杂,这个算法使用了O(N)的空间,另一个较好算法是:设置两个指针,指向首尾的位置,指向的值分别为a,b,判断a + b 与x的大小关系来移动指针,当a + b > x时,移动a,b中较大值的指针;当a + b = x时,返回true;当a + b < x时,移动a,b中较小值的指针!
code:
#include <stdio.h>#include <stdlib.h>#include <string.h>int Judge(int *a, int len, int x){ int Ascending = 0;//为1表示升序,否则降序 Ascending = a[1] > a[0] ? 1 : 0; int *CopyA = (int *)malloc(sizeof(int) * len); memset(CopyA, 0, sizeof(int) * len); //构建另一数组 int icount = 0; for(icount = 0; icount < len; icount++) { CopyA[icount] = x - a[icount]; } //比较两个指针移动的值,这里用索引代替指针 int i = len - 1, j = 0; while(i >= 0 && j < len) { if(a[i] > CopyA[j]) { switch(Ascending) { case 0: j++; break;//降序 case 1: i--; break;//升序 default:break; } } else if(a[i] == CopyA[j] && i != j) { return 1; } else { switch(Ascending) { case 0: i--; break;//降序 case 1: j++; break;//升序 default:break; } } } return 0;}int main(){ int a[] = {1, 2, 3, 4}; int len = 4; int x = 8; switch(Judge(a, len, x)) { case 0: printf("%d isn't exist!", x);break; case 1: printf("%d is exist!", x);break; default : break; } return 0;}
2、给定有n个数的数组a,其中超过一半的数为一个定值,在不进行排序、不开设额外数组的情况下,以最高效的算法找到这个数:int find(int *a, int n)
解:审题发现,要求条件蛮多的:不进行排序,不开设额外数组。这道题目其实我没有想到十分有效的方法,题解参考的编程之美2.3寻找发帖“水王”。
算法的思想是:既然在数组中某个定值出现的次数超过一半,那么每次从数组中删除两个不同的数字,直到数组中的元素全部相同为止,最后剩下的数组相同的元素一定就是这个定值,这里使用一个计数器cnt,对数组中某个数VeryNum进行计数,通过计数器的加减来找到该定值。
算法流程图:
code:
#include <stdio.h>#include <stdlib.h>int find(int *a, int n){ int VeryNum = 0; int cnt = 0; int i = 0; for(i = 0; i < n; i++) { if(cnt == 0) { VeryNum = a[i]; cnt = 1; } else { if(a[i] == VeryNum) { cnt++; } else { cnt--; } } } return VeryNum;}int main(void){ int a[] = {15, 15, 5, 15, 5, 15, 1}; int n = 7; printf("%d\n", find(a, n)); return 0;}
题目部分摘取自july CSDN网站:http://blog.csdn.net/v_july_v/article/details/11921021
注:1.本文版权归作者和CSDN所有,未经允许不得转载,侵权必究!
2.本博客与博客园上的博客为同一博客主:http://www.cnblogs.com/bestDavid/
- 人人校招笔试题
- 2014人人校招 笔试总结
- 校招笔试题
- 2014人人校招-judge算法题
- 人人校招
- 2012人人网校招山东济南java笔试
- 一些校招笔试题
- 淘宝校招笔试题
- 腾讯校招笔试题
- 网易校招笔试题
- 百度校招笔试题
- 搜狐校招笔试题
- 百度校招笔试题
- 阿里校招笔试题
- 恒生校招笔试题
- 2017校招笔试题
- 360校招笔试题
- 2014人人笔试题
- 你用过哪些操作系统?
- 在VS C++中调试DLL工程的方法
- Java/Flex使用相同密钥加密相同的信息,生成密文不同的解决方法
- mvc linq多表查询 viewModel
- VMware9无法将外部文件拖入虚拟机中
- 人人校招笔试题
- 今天看见了一个小项目,关于ftp编程
- LeetCode: Remove Duplicates from Sorted Array
- Cocos2dx 2.1.5 (2.1.4) 离线 API 手册
- Linux 下安装配置 JDK7
- Cocos2dx 2.1.5 (2.2.0) 离线 API 手册
- 软件开发相关文档模板
- Windows的ICMP后门实现
- git 命令说明