编程珠玑(基础篇)

第一章

关于计数排序的,题意如下:
输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7。如果在输入文件中有任何正数重复出现就是致命错误。没有其他数据与该正数相关联。
输出:按升序排列的输入正数的列表。
约束:最多有1MB的内存空间可用,有充足的磁盘存储空间可用。运行时间最多几分钟,运行时间为10秒就不需要进一步优化。
思路:利用位向量,当且仅当整数i在文件中出现时,第i位为1.最后检验每一位,如果该位为1,则输出相应的整数到输出文件中。
for [0, n)
	bit[i] = 0;
for each i in the input file
	bit[i] = 1;
for i = [0, n)
	if bit[i] == 1
		write(i);

第二章

给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的32位整数(文件中至少缺失一个这样的数)。在具有足够内存的情况下,如何解决该问题?如果有几个外部的“临时”文件可用,但是仅有几百字节的内存,又该如何解决该问题?

思路:二分搜索,采用已知包含至少一个缺失元素的一系列整数作为范围,并使用包含所有这些整数在内的文件表示这个范围,通过统计中间点之上和之下的元素来探测范围。由于这个范围中有一个缺失的元素,所以我们需要的那一半范围必然包含缺失的元素。
将一个n元一维向量向左旋转i个位置。例如当n=8且i=3时,向量abcdefgh旋转为defghabc。你能否仅使用数十个额外字节的存储空间,在正比与n的时间内完成向量的旋转?

思路:当时百度和微软亚洲研究院面试的时候都问过类似的题目,其实思路很简单,做字符串的翻转而已,空间复杂度为O(1),时间复杂度为O(n)。

reverse(0,i-1); //cbadefgh
reverse(i,n-1); // cbahgfed
reverse(0,n-1); //defghabc 


给定一个英文字典,找出其中的所有变位词集合。例如“pots”、“stop”、“tops”互为变位词,因为每一个单词都可以通过改变其他单词中字母的顺序来得到。

思路:百度实习生招聘时候的笔试题,书上的做法是对每个单词的字符进行排序,每个单词获得一个sign,比如tops的sign就是opst,然后找出具有相同sign的单词就是互为变位词。具体找出相同sign的方法可以是排序,或者是哈希。

第三章

数据决定程序结构

  1. 使用数组重新编写重复代码
  2. 封装复杂的数据结构
  3. 尽可能使用高级工具
  4. 从数据得出程序的结构

第四章,第五章

主要是关于二分查找的,对比一下两份代码
int binarysearch(int t) {
	int l,m,u;
	l=0;
	u=n-1;
	while (l <= u) {
		m=(l+u)/2;
		if (x[m] < t)
			l = m+1;
		else if (x[m] == t)
			return m;
		else 
			u = m-1;
	}
	return -1;
}
int badsearch(int t) {
	int l,u,m;
	l=0;
	u=n-1;
	while (l <= u) {
		m=(l+u)/2;
		if (x[m] < t)
			l=m;
		else if (x[m] > t)
			u=m;
		else 
			return m;
	}
	return -1;
}

其中badsearch函数在某些测试用例下不能起到缩小范围的作用,比如当x[ ] = {0,10,20,30,40},查找对象为40的时候,badsearch函数会陷入死循环。

你可能感兴趣的:(编程珠玑(基础篇))