- 浏览: 592000 次
- 性别:
- 来自: 西安
文章分类
- 全部博客 (365)
- Java 基础知识(笔试面试有用) (35)
- SQL 相关 (11)
- Oracle笔试 (1)
- Java 笔试面试 (11)
- LINUX (12)
- ExtJS (21)
- Javascript (17)
- WebGIS (2)
- 软件工程 (3)
- 数据库 (17)
- 项目管理 (63)
- 工作流 (2)
- 计算机网络 (3)
- ZigBee技术及应用 (24)
- 单片机(AVR Studio) (7)
- 项目人力资源管理 (3)
- 项目管理高级知识 (4)
- JAVA技术 (12)
- 项目管理中的概念 (3)
- SQL SERVER (1)
- C++ (1)
- C/C++编程经验 (12)
- C和C++面试笔试题 (12)
- 其他IT技术笔试面试 (6)
- 名企笔试面试集锦 (16)
- 非技术 (10)
- C#相关 (1)
- Matlab相关 (2)
- 计算机专业课相关 (2)
- Web Service (1)
- Excel 使用 (1)
- PhotoShop相关 (4)
- ASP 相关 (2)
- android (1)
- Java WEB 相关 (1)
- web 安全相关 (7)
- 网络安全 (1)
- IBatis (1)
- web 开发技巧 (2)
- css 相关 (1)
- Ruby相关 (2)
- 生活 (3)
- 操作系统安全相关 (6)
- 操作系统相关 (1)
- PHP相关 (3)
- 开发经验 (12)
- Redis (1)
最新评论
1.给定如下的n*n的数字矩阵,每行从左到右是严格递增, 每列的数据也是严格递增
1 2 3
3 5 6
4 8 9
现在要求设计一个算法, 给定一个数k 判断出k是否在这个矩阵中。 描述算法并且给出时间复杂度(不考虑载入矩阵的消耗)
2.设 一个64位整型n,各个bit位是1的个数为a个. 比如7, 2进制就是 111, 所以a为3。
现在给出m个数, 求各个a的值。要求代码实现。
大多数的读者都会有这样的反应:这个题目也太简单了吧,解法似乎也相当地单一,不会有太多的曲折分析或者峰回路转之处。那么面试者到底能用这个题目考察我们什么呢?事实上,在编写程序的过程中,根据实际应用的不同,对存储空间或效率的要求也不一样。比如在PC上的程序编写与在嵌入式设备上的程序编写就有很大的差别。我们可以仔细思索一下如何才能使效率尽可能地“高”。
【解法一】
可以举一个八位的二进制例子来进行分析。对于二进制操作,我们知道,除以一个2,原来的数字将会减少一个0。如果除的过程中有余,那么就表示当前位置有一个1。
以10 100 010为例;
第一次除以2时,商为1 010 001,余为0。
第二次除以2时,商为101 000,余为1。
因此,可以考虑利用整型数据除法的特点,通过相除和判断余数的值来进行分析。于是有了如下的代码。
代码清单2-1
int Count(int v)
{
int num = 0;
while(v)
{
if(v % 2 == 1)
{
num++;
}
v = v/ 2;
}
return num;
}
【解法二】使用位操作
前面的代码看起来比较复杂。我们知道,向右移位操作同样也可以达到相除的目的。唯一不同之处在于,移位之后如何来判断是否有1存在。对于这个问题,再来看看一个八位的数字:10 100 001。
在向右移位的过程中,我们会把最后一位直接丢弃。因此,需要判断最后一位是否为1,而“与”操作可以达到目的。可以把这个八位的数字与00000001进行“与”操作。如果结果为1,则表示当前八位数的最后一位为1,否则为0。代码如下:
代码清单2-2
int Count(int v)
{
int num = 0;
While(v)
{
num += v &0x01;
v >>= 1;
}
return num;
}
【解法三】
位操作比除、余操作的效率高了很多。但是,即使采用位操作,时间复杂度仍为O(log2v),log2v为二进制数的位数。那么,还能不能再降低一些复杂度呢?如果有办法让算法的复杂度只与“1”的个数有关,复杂度不就能进一步降低了吗?
同样用10 100 001来举例。如果只考虑和1的个数相关,那么,我们是否能够在每次判断中,仅与1来进行判断呢?
为了简化这个问题,我们考虑只有一个1的情况。例如:01 000 000。
如何判断给定的二进制数里面有且仅有一个1呢?可以通过判断这个数是否是2的整数次幂来实现。另外,如果只和这一个“1”进行判断,如何设计操作呢?我们知道的是,如果进行这个操作,结果为0或为1,就可以得到结论。
如果希望操作后的结果为0,01 000 000可以和00 111 111进行“与”操作。
这样,要进行的操作就是 01 000 000 &(01 000 000 – 00 000 001)= 01 000 000 &
00 111 111 = 0。
因此就有了解法三的代码:
代码清单2-3
int Count(int v)
{
int num = 0;
while(v)
{
v &= (v-1);
num++;
}
return num;
}
【解法四】使用分支操作
解法三的复杂度降低到O(M),其中M是v中1的个数,可能会有人已经很满足了,只用计算1的位数,这样应该够快了吧。然而我们说既然只有八位数据,索性直接把0~255的情况都罗列出来,并使用分支操作,可以得到答案,代码如下:
代码清单2-4
int Count(int v)
{
int num = 0;
switch (v)
{
case 0x0:
num = 0;
break;
case 0x1:
case 0x2:
case 0x4:
case 0x8:
case 0x10:
case 0x20:
case 0x40:
case 0x80:
num = 1;
break;
case 0x3:
case 0x6:
case 0xc:
case 0x18:
case 0x30:
case 0x60:
case 0xc0:
num = 2;
break;
//...
}
return num;
}
解法四看似很直接,但实际执行效率可能会低于解法二和解法三,因为分支语句的执行情况要看具体字节的值,如果a =0,那自然在第1个case就得出了答案,但是如果a =255,则要在最后一个case才得出答案,即在进行了255次比较操作之后!
看来,解法四不可取!但是解法四提供了一个思路,就是采用空间换时间的方法,罗列并直接给出值。如果需要快速地得到结果,可以利用空间或利用已知结论。这就好比已经知道计算1+2+ … +N的公式,在程序实现中就可以利用公式得到结论。
最后,得到解法五:算法中不需要进行任何的比较便可直接返回答案,这个解法在时间复杂度上应该能够让人高山仰止了。
【解法五】查表法
代码清单2-5
/* 预定义的结果表 */
int countTable[256] =
{
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3,
3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3,
4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4,
3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3,
4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6,
6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4,
5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3,
4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4,
4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6,
7, 6, 7, 7, 8
};
int Count(int v)
{
//check parameter
return countTable[v];
}
这是个典型的空间换时间的算法,把0~255中“1”的个数直接存储在数组中,v作为数组的下标,countTable[v]就是v中“1”的个数。算法的时间复杂度仅为O(1)。
在一个需要频繁使用这个算法的应用中,通过“空间换时间”来获取高的时间效率是一个常用的方法,具体的算法还应针对不同应用进行优化。
扩展问题
1. 如果变量是32位的DWORD,你会使用上述的哪一个算法,或者改进哪一个算法?
2. 另一个相关的问题,给定两个正整数(二进制形式表示)A和B,问把A变为B需要改变多少位(bit)?也就是说,整数A 和B 的二进制表示中有多少位是不同的?
发表评论
-
IT工程师面试经验
2013-09-03 10:05 812(1)穿着:IT面试不像销售,不需要西装革履。得体大方,整 ... -
360 笔试题
2012-10-06 08:08 4143360笔试题 一、主观 ... -
华为Java笔试题
2012-10-01 10:36 2222一、 单项选择题 1.Java是从( )语言改进重新设计。 ... -
北京数码视讯,神州软件,华为,用友软件,趋势科技面试心得
2012-09-29 19:27 4977在不到一个月的找工作历程中,感受到了很多,也收获很多 ... -
人人网Java笔试题
2012-09-19 08:49 705从网上找到一份人人网JAVA的笔试题,做了一下,受益匪浅 ... -
华为历年机试题
2012-09-17 21:30 10331.找出一个数组中满足2^N的元素 #include < ... -
百度算法笔试题01
2012-09-17 10:19 13342009百度实习笔试题Zz 一、编程题(30分)输入:N(整数 ... -
名企笔试题
2012-09-12 18:02 961腾讯2011.10.15校园招聘 ... -
Google 技术 面试
2012-09-06 09:23 10521.谷歌面试题:给定能随机生成整数1到5的函数,写出能随 ... -
Google 面试 01
2012-09-06 09:22 917今年年初的时候 申请 ... -
Google 笔试01
2012-09-06 09:20 731题型:9道单选题+3道 ... -
海量数据处理总结
2012-09-06 08:40 678大数据量的问题是很 ... -
2006百度笔试题
2012-09-05 11:10 8962006百度笔试题 ... -
微软笔试-01
2012-09-01 15:40 6801.把二元查找树转变成排序的双向链表 题目: 输入 ... -
百度面试 01
2012-08-28 14:08 794百度技术研发笔试题目 /*百度面试题 ...
相关推荐
大疆求职算法笔试题 大疆求职算法笔试题大疆求职算法笔试题大疆求职算法笔试题大疆求职算法笔试题大疆求职算法笔试题大疆求职算法笔试题
百度校园招聘笔试试题-深度学习算法研发工程师.docx百度校园招聘笔试试题-深度学习算法研发工程师.docx百度校园招聘笔试试题-深度学习算法研发工程师.docx百度校园招聘笔试试题-深度学习算法研发工程师.docx百度校园...
北京-百度计算机视觉算法工程师笔试-回忆版.pdf
百度历年笔试试题汇总 技术类笔试试题 算法 数据结构等
百度 2014校园招聘笔试试题--深度学习算法研发工程师.docx百度 2014校园招聘笔试试题--深度学习算法研发工程师.docx百度 2014校园招聘笔试试题--深度学习算法研发工程师.docx百度 2014校园招聘笔试试题--深度学习...
百度公司两年来的笔试题,快来看啊
百度2014校园招聘笔试试题-研发工程师笔试题.docx
百度技术研发笔试题,涉及数据结构及相关算法,哈希等知识
百度网上笔试题及答案 用C语言实现一个revert函数,它的功能是将输入的字符串在原串上倒序后返回。 2 编程: 用C语言实现函数void * memmove(void *dest,const void *src,size_t n)。memmove函数的功能是拷贝src...
百度2010-2011年各部门招聘笔试题及面经总结.doc 百度2014校园招聘笔试试题-产品经理笔试题.doc 百度2014校园招聘笔试试题-北京站未知岗位.docx 百度2014校园招聘笔试试题-南京PC客户端开发笔试题.doc 百度2014校园...
百度笔试题 汉略曾考的测试题目 16道C语言面试题例子 死循环(Infinite loops) 数据声明(Data declarations) 位操作(Bit manipulation) 访问固定的内存位置(Accessing fixed memory locations) 中断...
百度的面试题,招聘iOS开发工程师,解答详细.
算法面试100题全部答案集锦.pdf搜狐2013校招笔试题.pdf搜狗2015校园招聘研发类笔试题.pdf浙江大华2015届校园招聘算法、软件类笔试题.pdf百度2015产品经理.pdf百度2015前端研发笔试卷.pdf百度2015大数据云计算研发笔...
2015校园招聘笔试题大合集,汇集百度、腾讯、阿里等多家大型互联网企业的面试题,非常具有参考价值。 内容包括: 360校园招聘2015届技术类笔试题.pdf ... 浙江大华2015届校园招聘算法、软件类笔试题.pdf
百度面试必备笔试试题。.../*百度面试题算法: 1。将集合按照大小从小到大排序,组成待处理的集合列表。 2。取出待处理集合列表中最小的集合,对于集合的每个元素,依次在其他集合中搜索 是否有此元素存在:
百度_新浪_盛大2011年面试笔试算法题收集(含答案)_java
2015创新工场校招研发笔试题.pdf 2015小米校招技术类笔试题.pdf 360校园招聘2015届技术类笔试题.pdf 4399游戏2015校园招聘游戏开发类笔试题.pdf 人人网2015研发笔试卷B.pdf 人人网2015研发笔试卷C.pdf 搜狗2015校园...
百度的笔试题目,2010年的,注重算法,祝大家好运啊
2011年9月24日百度成都笔试题回忆,研发类通用试卷
2012十月下旬腾讯,网易游戏,百度最新校园招聘笔试题集锦