百度最新面试题集锦

百度最新面试题集锦

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

转载请标明出处,原文地址:http://blog.csdn.net/hackbuteer1/article/details/7348968

1、实现一个函数,对一个正整数n,算得到1须要的最少操作次数。操作规则为:假设n为偶数,将其除以2;假设n为奇数,能够加1或减1;一直处理下去。

样例:
func(7) = 4,能够证明最少须要4次运算
n = 7
n-1 6
n/2 3
n-1 2
n/2 1
要求:实现函数(实现尽可能高效) int func(unsign int n);n为输入,返回最小的运算次数。给出思路(文字描写叙述),完毕代码,并分析你算法的时间复杂度。

答:

int func(unsigned int n)
{
	if(n == 1)
		return 0;
	if(n % 2 == 0)
		return 1 + func(n/2);
	int x = func(n + 1);
	int y = func(n - 1);
	if(x > y)
		return y+1;
	else
		return x+1;
}

如果n表示成二进制有x bit,能够看出计算复杂度为O(2^x),也就是O(n)。
将n转换到二进制空间来看(比方7为111,6为110):
– 假设最后一位是0,则相应于偶数,直接进行除2操作。
– 假设最后一位是1,情况则有些复杂。
**假设最后几位是???01,则有可能为???001,???1111101。在第一种情况下,显然应该-1;在另外一种情况下-1和+1终于须要的步数同样。所以在???01的情况下,应该选择-1操作。
**假设最后几位是???011,则有可能为???0011,???11111011。在第一种情况下,+1和-1终于须要的步数同样;在另外一种情况下+1步数更少些。所以在???011的情况下,应该选择+1操作。
**假设最后有很多其它的连续1,也应该选择+1操作。

假设最后剩下的各位都是1,则有11时应该选择-1;111时+1和-1同样;1111时应选择+1;大于四个1时也应该选择+1;

int func(unsigned int n)
{
	if(n == 1)
		return 0;
	if(n % 2 == 0)
		return 1 + func(n/2);
	if(n == 3)
		return 2;
	if(n&2)
		return 1 + func(n+1);
	else
		return 1 + func(n-1);
}

由以上的分析可知,奇数的时候加1或减1,全然取决于二进制的后两位,假设后两位是10、00那么肯定是偶数,选择除以2,假设后两位是01、11,那么选择结果会不一样的,假设是*****01,那么选择减1,假设是*****11,那么选择加1,特殊情况是就是n是3的时候,选择减1操作。
非递归代码例如以下:

// 非递归写法
int func(int n)
{
	int count = 0;
	while(n > 1)
	{
		if(n % 2 == 0)
			n >>= 1;
		else if(n == 3)
			n--;
		else
		{
			if(n&2)      // 二进制是******11时
				n++;
			else         // 二进制是******01时
				n--;
		}
		count++;
	}
	return count;
}

第二种写法例如以下:

// 非递归写法
int func(int n)
{
	int count = 0;
	while(n > 1)
	{
		if(n % 2 == 0)            // n % 4等于0或2
			n >>= 1;
		else if(n == 3)
			n--;
		else
			n += (n % 4 - 2);     // n % 4等于1或3
		count++;
	}
	return count;
}

2、找到满足条件的数组


给定函数d(n)=n+n的各位之和,n为正整数,如d(78)=78+7+8=93。这样这个函数能够看成一个生成器,如93能够看成由78生成。
定义数A:数A找不到一个数B能够由d(B)=A,即A不能由其它数生成。如今要敲代码,找出1至10000里的全部符合数A定义的数。
回答:
申请一个长度为10000的bool数组,每一个元素代表相应的值能否够有其他数生成。開始时将数组中的值都初始化为false。
因为大于10000的数的生成数必然大于10000,所以我们仅仅需遍历1到10000中的数,计算生成数,并将bool数组中相应的值设置为true,表示这个数能够有其他数生成。
最后bool数组中值为false的位置相应的整数就是不能由其他数生成的。
3、一个大的含有50M个URL的记录,一个小的含有500个URL的记录,找出两个记录里同样的URL。

回答:
首先使用包括500个url的文件创建一个hash_set。
然后遍历50M的url记录,假设url在hash_set中,则输出此url并从hash_set中删除这个url。
全部输出的url就是两个记录里同样的url。
4、海量日志数据,提取出某日訪问百度次数最多的那个IP。
回答:
假设日志文件足够的大,大到不能全然载入到内存中的话。
那么能够考虑分而治之的策略,依照IP地址的hash(IP)%1024值,将海量日志存储到1024个小文件里。每一个小文件最多包括4M个IP地址。
对于每一个小文件,能够构建一个IP作为key,出现次数作为value的hash_map,并记录当前出现次数最多的1个IP地址。
有了1024个小文件里的出现次数最多的IP,我们就能够轻松得到整体上出现次数最多的IP。
5、有10个文件,每一个文件1G,每一个文件的每一行都存放的是用户的query,每一个文件的query都可能反复。怎样依照query的频度排序?
回答:
 1)读取10个文件,依照hash(query)%10的结果将query写到相应的文件里。这样我们就有了10个大小约为1G的文件。随意一个query仅仅会出如今某个文件里。
 2)对于1)中获得的10个文件,分别进行例如以下操作
  -利用hash_map(query,query_count)来统计每一个query出现的次数。
  -利用堆排序算法对query依照出现次数进行排序。
  -将排序好的query输出的文件里。
  这样我们就获得了10个文件,每一个文件里都是按频率排序好的query。
 3)对2)中获得的10个文件进行归并排序,并将终于结果输出到文件里。

6、蚂蚁爬杆问题
 有一根27厘米长的细木杆,在第3厘米,7厘米,11厘米,17厘米,23厘米这五个位置上各有一仅仅蚂蚁,木杆非常细,不能同一时候通过两仅仅蚂蚁,開始时,蚂蚁的头朝向左还是右是随意的,他们仅仅会朝前走或掉头,但不会后退,当两仅仅蚂蚁相遇后,蚂蚁会同一时候掉头朝反方向走,如果蚂蚁们每秒钟能够走1厘米的距离。求全部蚂蚁都离开木杆的最小时间和最大时间。
 答案:
 两仅仅蚂蚁相遇后,各自掉头朝相反方向走。假设我们不考虑每一个蚂蚁的详细身份,这和两仅仅蚂蚁相遇后,打个招呼继续向前走没有什么差别。
 全部蚂蚁都离开木杆的最小时间为
 max(min(3,27-3),min(7,27-7), min(11,27-11), min(17,27-17),min(23,27-23))=11
 全部蚂蚁都离开木杆的最大时间为
 max(max(3,27-3),max(7,27-7), max(11,27-11), max(17,27-17),max(23,27-23))=24

7、当在浏览器中输入一个url后回车,后台发生了什么?比方输入url后,你看到了百度的首页,那么这一切是怎样发生的呢?
回答:
  简单来说有下面步骤:
  1、查找域名相应的IP地址。这一步会依次查找浏览器缓存,系统缓存,路由器缓存,ISPDNS缓存,根域名server。
  2、向IP相应的server发送请求。
  3、server响应请求,发回网页内容。
  4、浏览器解析网页内容。
当然,因为网页可能有重定向,或者嵌入了图片,AJAX,其他子网页等等,这4个步骤可能重复进行多次才干将终于页面展示给用户。

8、推断两棵树是否相等,请实现两棵树是否相等的比較,相等返回1,否则返回其它值,并说明算法复杂度。

数据结构为:

typedef struct TreeNode
{
	char c;
	TreeNode *leftchild;
	TreeNode *rightchild;
}TreeNode;

函数接口为:int CompTree(TreeNode* tree1,TreeNode* tree2);

注:A、B两棵树相等当且仅当RootA->c==RootB–>c,并且A和B的左右子树相等或者左右互换相等。

递归方法:

bool CompTree(TreeNode *tree1, TreeNode *tree2)
{
	if(tree1 == NULL && tree2 == NULL)
		return true;
	if(tree1 == NULL || tree2 == NULL)
		return false;
	if(tree1->c != tree2->c)
		return false;
	if( (CompTree(tree1->leftchild, tree2->leftchild) && CompTree(tree1->rightchild, tree2->rightchild)) || CompTree(tree1->leftchild, tree2->rightchild) && CompTree(tree1->rightchild, tree2->leftchild))
		return true;
}

时间复杂度:
 在树的第0层,有1个节点,我们会进行1次函数调用;
 在树的第1层,有2个节点,我们可能会进行4次函数调用;
 在树的第2层,有4个节点,我们可能会进行16次函数调用;
 ….
 在树的第x层,有2^x个节点,我们可能会进行(2^x)^2次函数调用;
 所以如果总节点数为n,则算法的复杂度为O(n^2)。

腾讯面试题:求一个论坛的在线人数,如果有一个论坛,其注冊ID有两亿个,每一个ID从登陆到退出会向一个日志文件里记下登陆时间和退出时间,要求写一个算法统计一天中论坛的用户在线分布,取样粒度为秒。
回答:
  一天总共同拥有3600*24=86400秒。
  定义一个长度为86400的整数数组intdelta[86400],每一个整数相应这一秒的人数变化值,可能为正也可能为负。開始时将数组元素都初始化为0。
  然后依次读入每一个用户的登录时间和退出时间,将与登录时间相应的整数值加1,将与退出时间相应的整数值减1。
  这样处理一遍后数组中存储了每秒中的人数变化情况。
  定义另外一个长度为86400的整数数组intonline_num[86400],每一个整数相应这一秒的论坛在线人数。
  如果一天開始时论坛在线人数为0,则第1秒的人数online_num[0]=delta[0]。第n+1秒的人数online_num[n]=online_num[n-1]+delta[n]。
  这样我们就获得了一天中随意时间的在线人数。

9、三个警察和三个囚徒的过河问题

  三个警察和三个囚徒共同旅行。一条河挡住了去路,河边有一条船,可是每次仅仅能载2人。存在例如以下的危急:不管在河的哪边,当囚徒人数多于警察的人数时,将有警察被囚徒杀死。问题:请问怎样确定渡河方案,才干保证6人安全无损的过河。
答案:第一次:两囚徒同过,回一囚徒
第二次:两囚徒同过,回一囚徒
第三次:两警察同过,回一囚徒一警察(此时对岸还剩下一囚徒一警察,是安全状态)
第四次:两警察同过,回一囚徒(此时对岸有3个警察,是安全状态)
第五次:两囚徒同过,回一囚徒
第六次:两囚徒同过;over

10、从300万字符串中找到最热门的10条
搜索的输入信息是一个字符串,统计300万输入信息中的最热门的前10条,我们每次输入的一个字符串为不超过255byte,内存使用仅仅有1G。请描写叙述思想,写出算法(c语言),空间和时间复杂度。
答案:
  300万个字符串最多(如果没有反复,都是最大长度)占用内存3M*1K/4=0.75G。所以能够将全部字符串都存放在内存中进行处理。
  能够使用key为字符串(其实是字符串的hash值),值为字符串出现次数的hash来统计每一个每一个字符串出现的次数。并用一个长度为10的数组/链表来存储眼下出现次数最多的10个字符串。
  这样空间和时间的复杂度都是O(n)。
11、怎样找出字典中的兄弟单词。给定一个单词a,假设通过交换单词中字母的顺序能够得到另外的单词b,那么定义b是a的兄弟单词。如今给定一个字典,用户输入一个单词,怎样依据字典找出这个单词有多少个兄弟单词?
答案:
  使用hash_map和链表。
  首先定义一个key,使得兄弟单词有同样的key,不是兄弟的单词有不同的key。比如,将单词按字母从小到大又一次排序后作为其key,比方bad的key为abd,good的key为dgoo。
  使用链表将全部兄弟单词串在一起,hash_map的key为单词的key,value为链表的起始地址。
  開始时,先遍历字典,将每一个单词都依照key增加到相应的链表其中。当须要找兄弟单词时,仅仅需求取这个单词的key,然后到hash_map中找到相应的链表就可以。
  这样创建hash_map时时间复杂度为O(n),查找兄弟单词时时间复杂度是O(1)。
12、找出数组中出现次数超过一半的数,如今有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数。
答案1:
  创建一个hash_map,key为数组中的数,value为此数出现的次数。遍历一遍数组,用hash_map统计每一个数出现的次数,并用两个值存储眼下出现次数最多的数和相应出现的次数。
  这样能够做到O(n)的时间复杂度和O(n)的空间复杂度,满足题目的要求。
  可是没有利用“一个数出现的次数超过了一半”这个特点。或许算法还有提高的空间。
答案2:
  使用两个变量A和B,当中A存储某个数组中的数,B用来计数。開始时将B初始化为0。
  遍历数组,假设B=0,则令A等于当前数,令B等于1;假设当前数与A同样,则B=B+1;假设当前数与A不同,则令B=B-1。遍历结束时,A中的数就是要找的数。
  这个算法的时间复杂度是O(n),空间复杂度为O(1)。

13、找出被改动过的数字
      n个空间(当中n<1M),存放a到a+n-1的数,位置随机且数字不反复,a为正且未知。如今第一个空间的数被误设置为-1。已经知道被改动的数不是最小的。请找出被改动的数字是多少。
  比如:n=6,a=2,原始的串为5,3,7,6,2,4。如今被别人改动为-1,3,7,6,2,4。如今希望找到5。
回答:
  因为改动的数不是最小的,所以遍历第二个空间到最后一个空间能够得到a的值。
  a到a+n-1这n个数的和是total=na+(n-1)n/2。
  将第二个至最后一个空间的数累加获得sub_total。
  那么被改动的数就是total-sub_total。

14、设计DNSserver中cache的数据结构。
  要求设计一个DNS的Cache结构,要求可以满足每秒5000以上的查询,满足IP数据的高速插入,查询的速度要快。(题目还给出了一系列的数据,比方:网站数总共为5000万,IP地址有1000万,等等)
回答:
  DNSserver实现域名到IP地址的转换。
  每一个域名的平均长度为25个字节(预计值),每一个IP为4个字节,所以Cache的每一个条目须要大概30个字节。
  总共50M个条目,所以须要1.5G个字节的空间。能够放置在内存中。(考虑到每秒5000次操作的限制,也仅仅能放在内存中。)
  能够考虑的数据结构包含hash_map,字典树,红黑树等等。
15、找出给定字符串相应的序号。
  序列Seq=[a,b,…z,aa,ab…az,ba,bb,…bz,…,za,zb,…zz,aaa,…]类似与excel的排列,随意给出一个字符串s=[a-z]+(由a-z字符组成的随意长度字符串),请问s是序列Seq的第几个。
回答:
  注意到每满26个就会向前进一位,类似一个26进制的问题。
  比方ab,则位置为26*1+2;
  比方za,则位置为26*26+1;
  比方abc,则位置为26*26*1+26*2+3;
16、找出第k大的数字所在的位置。写一段程序,找出数组中第k大小的数,输出数所在的位置。比如{2,4,3,4,7}中,第一大的数是7,位置在4。第二大、第三大的数都是4,位置在1、3随便输出哪一个均可。
答案:
   先找到第k大的数字,然后再遍历一遍数组找到它的位置。所以题目的难点在于怎样最高效的找到第k大的数。
 我们能够通过高速排序,堆排序等高效的排序算法对数组进行排序,然后找到第k大的数字。这样整体复杂度为O(NlogN)。
 我们还能够通过二分的思想,找到第k大的数字,而不必对整个数组排序。从数组中随机选一个数t,通过让这个数和其他数比較,我们能够将整个数组分成了两部分而且满足,{x,xx,…,t}<{y,yy,…}。
 在将数组分成两个数组的过程中,我们还能够记录每一个子数组的大小。这样我们就能够确定第k大的数字在哪个子数组中。
 然后我们继续对包括第k大数字的子数组进行相同的划分,直到找到第k大的数字为止。
 平均来说,因为每次划分都会使子数组缩小到原来1/2,所以整个过程的复杂度为O(N)。

17、给40亿个不反复的unsigned int的整数,没排过序的,然后再给几个数,怎样高速推断这几个数是否在那40亿个数其中?
答案:
  unsigned int的取值范围是0到2^32-1。我们能够申请连续的2^32/8=512M的内存,用每个bit相应一个unsigned int数字。首先将512M内存都初始化为0,然后每处理一个数字就将其相应的bit设置为1。当须要查询时,直接找到相应bit,看其值是0还是1就可以。

18、在一个文件里有10G个整数,乱序排列,要求找出中位数。内存限制为2G。
回答:
  最好还是如果10G个整数是64bit的。
  2G内存能够存放256M个64bit整数。
  我们能够将64bit的整数空间平均分成256M个取值范围,用2G的内存对每一个取值范围内出现整数个数进行统计。这样遍历一边10G整数后,我们便知道中数在那个范围内出现,以及这个范围内总共出现了多少个整数。
  假设中数所在范围出现的整数比較少,我们就能够对这个范围内的整数进行排序,找到中数。假设这个范围内出现的整数比較多,我们还能够採用相同的方法将此范围再次分成多个更小的范围(256M=2^28,所以最多须要3次就能够将此范围缩小到1,也就找到了中数)。
19、时分秒针在一天之类重合多少次?(24小时)

2次 

而时针和分针重合了22次。

20、将多个集合合并成没有交集的集合。
  给定一个字符串的集合,格式如:{aaabbbccc},{bbbddd},{eeefff},{ggg},{dddhhh}要求将当中交集不为空的集合合并,要求合并完毕后的集合之间无交集,比如上例应输出{aaabbbcccdddhhh},{eeefff},{ggg}。
  (1)请描写叙述你解决问题的思路;
  (2)请给出基本的处理流程,算法,以及算法的复杂度
  (3)请描写叙述可能的改进。
回答:
  集合使用hash_set来表示,这样合并时间复杂度比較低。
  1、给每一个集合编号为0,1,2,3…
  2、创建一个hash_map,key为字符串,value为一个链表,链表节点为字符串所在集合的编号。遍历全部的集合,将字符串和相应的集合编号插入到hash_map中去。
  3、创建一个长度等于集合个数的int数组,表示集合间的合并关系。比如,下标为5的元素值为3,表示将下标为5的集合合并到下标为3的集合中去。開始时将全部值都初始化为-1,表示集合间没有互相合并。在集合合并的过程中,我们将全部的字符串都合并到编号较小的集合中去。
   遍历第二步中生成的hash_map,对于每一个value中的链表,首先找到最小的集合编号(有些集合已经被合并过,须要顺着合并关系数组找到合并后的集合编号),然后将链表中全部编号的集合都合并到编号最小的集合中(通过更改合并关系数组)。
  4、如今合并关系数组中值为-1的集合即为终于的集合,它的元素来源于全部直接或间接指向它的集合。
  算法的复杂度为O(n),当中n为全部集合中的元素个数。
  题目中的样例:
  0:{aaabbbccc}
  1:{bbbddd}
  2:{eeefff}
  3:{ggg}
  4:{dddhhh}
  生成的hash_map,和处理完每一个值后的合并关系数组分别为
  aaa:0。[-1,-1,-1,-1,-1]
  bbb:0,1。[-1,0,-1,-1,-1]
  ccc:0。[-1,0,-1,-1,-1]
  ddd:1,4。[-1,0,-1,-1,0]
  eee:2。[-1,0,-1,-1,0]
  fff:2。[-1,0,-1,-1,0]
  ggg:3。[-1,0,-1,-1,0]
  hhh:4。[-1,0,-1,-1,0]
  所以合并完后有三个集合,第0,1,4个集合合并到了一起,
 21、平面内有11个点,由它们连成48条不同的直,由这些点可连成多少个三角形?
解析:
首先你要分析,平面中有11个点,假设这些点中随意三点都没有共线的,那么一共应该有C(11,2)=55,  但是,题目中说能够连接成48条直线,那么这11个点中必然有多点共线的情况。  55-48=7,从7来分析:
如果有一组三个点共线,那么能够组成的直线在55的基础上应该减去C(3,2)-1=2     2*3=6≠7,因此,能够断定不仅有三点共线的,也可能有四个点共线的可能。
如果有一组四个点共线,那么能够组成的直线在55的基础上应该减去C(4,2)-1=5
(备注,五个点共线的可能不存在,由于,C(5,2)-1=9>7,故不可能有五条直线共线。)

因此,三点共线少2条,4点共线少5条,仅仅有一个4点共线,一个3点共线才干满足条件,其余情况不能满足少了7条直线。
那么,这11个点能组成的三角形的个数为,C(11,3)-C(3,3)-C(4,3)=165-1-4=160  (备注,三个点共线不能组成三角形)


转载请标明出处,原文地址:http://blog.csdn.net/hackbuteer1/article/details/7348968

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/118076.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • windows server 2008 web服务器搭建

    windows server 2008 web服务器搭建在众多小企业中,Web服务器的应用也需是最广泛的,企业网站的建立促进了服务器进驻中小企业,而Web服务器的建立也越来越多。而面对诸多的Web服务器应用系统,可以说是多种多样,有大家最熟悉的微软的IIS,也有开源的Apache,还有大型网站应用比较多的Unix,总之可以说是各有各的优点。  今天介绍的是,微软的IIS,因其图形界面的操作方式,给人以直观的操作感受,部署简便,是很多用户的首选,而Apache的部署要相对复杂,一般新手很难马上上手,所以这里先跟大家讲解一下IIS7.0的搭建Web服务器的方法。

  • Arduino编程之Serial.println()和Serial.print()

    Arduino编程之Serial.println()和Serial.print()Arduino编程之Serial.println()和Serial.print()Arduino的输出基本就用两个函数print和println,区别在于后者比前者多了回车换行Serial.println(data)从串行端口输出数据,跟随一个回车(ASCII13,或’r’)和一个换行符(ASCII10,或’n’)。这个函数所取得的值与Serial.print()一样。Ser…

  • pycharm激活码2021最新(最新序列号破解)[通俗易懂]

    pycharm激活码2021最新(最新序列号破解),https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • 惠普电脑u盘重装系统步骤_惠普电脑优盘装系统步骤「建议收藏」

    惠普电脑u盘重装系统步骤_惠普电脑优盘装系统步骤「建议收藏」惠普是一家全球性的科技公司,旗下有三大业务,计算机就是其中一种。购买惠普电脑的朋友不在少数,给我们提供了科技领先的产品和服务。那么惠普电脑如何安装系统呢?下面就教大家惠普电脑优盘装系统步骤,有需要的朋友们赶紧来学习一下吧。惠普电脑优盘装系统步骤阅读1、打开浏览器搜索云骑士官网,找到云骑士官网并点击打开。2、首先在官网下载云骑士一键重装系统软件,下载好以后打开云骑士装机大师。3、将U盘插在电脑的U…

  • suse linux rpm 安装

    suse linux rpm 安装安装rpm包时遇到error:Faileddependencies:错误在linux下安装rpm包时经常会遇到下面这个问题:error:Faileddependencies:……………………………………………..省略号表示安装此rpm缺少的包。遇到此问题时可以在安装rpm包命令的后面加两个参数,如:

  • 分页插件

    分页插件分页插件介绍分页可以将很多条结果进行分页显示。如果当前在第一页,则没有上一页。如果当前在最后一页,则没有下一页。需要明确当前是第几页,这一页中显示多少条结果。MyBatis分页插件总结在企业

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号