看起来很困难的问题也可以有一个简单的、意想不到的答案
##二分搜索
在程序设计中,二分搜索最常见的应用是在有序数组中搜索元素。顺序搜索在搜索一个具有n个元素表时,平均需要n/2次比较,而二分搜索仅仅进行不超过 l o g 2 n log_2n log2n次比较就可以完成。
###问题A
分析问题A,最多40亿个数据:暗示了至少缺一个整数;仅有几百个字节暗示了不能使用第一章介绍的位图算法(当然你使用n趟算法也不是很合理,因为需要几十万趟…)。
解决该问题需要明确的点:为了使用二分搜索技术,我们就必须:
- 定义一个范围:包含至少一个缺失元素的一系列整数
- 在该范围内表现元素的方式:文件
- 确定哪一半范围存在缺失整数的探测方法:统计中间点之上和之下的元素来探测范围
二分搜索应用广泛:求根程序使用二分搜索技术;树数据结构;程序调试
##旋转操作
###问题B
该问题的旋转操作对应于交换相邻的不同大小的内存块。该问题有以下几种解决方案:- solution1:将x的前i个元素复制到临时数组里,这种方法产生了过大的存储空间的消耗。
- solution2:定义一个函数将x向左旋转一个位置(满足时间正比于n)然后调用函数i次,这种方法产生了过多的运行时间消耗。
但是要想在有限的资源里面解决该问题,显然需要更复杂的程序。有以下几个思路:
- solution1:移动x[0]到临时变量t,然后移动x[i]到x[0],x[2i]到x[i],依此类推,直至返回到取x[0]中的元素,此时改为从t取值然后终止。然后从x[1]继续重复上述步骤,知道x[i-1]。
- solution2:将旋转向量x分为两个向量ab,需要的是得到ba。假设a比b短,将b分为 b l b_l bl和 b r b_r br,使得 b r b_r br与a具有相同长度。交换a和 b r b_r br,得到 b r b l a b_rb_la brbla。再交换 b r b l b_rb_l brbl,所以采用迭代的思想,迭代的结束条件是 b r b_r br或 b l b_l bl任意一个长度为0。
- solution3:假定我们拥有一个函数可以将数组特定部分的元素求逆。从ab开始,首先对a求逆得到 a r b a^rb arb,然后对b求逆得到 a r b r a^rb^r arbr。最后整体求逆,得到 ( a r b r ) r (a^rb^r)^r (arbr)r
##排序
###问题C
这个判断单词是否是变位词,比较普遍。而且解决这个问题的许多方法都出奇地低效和复杂。我们分析问题,发现,要解决这个问题,可以先使得相同变位词有相同的标识。然后再集中具有相同标识的单词。要解决第一个问题可以将单词中的字母排序作为标识。要解决第二个问题,就是将所有的单词按照其标识的顺序排序。
##习题
没有难以理解的