时间复杂度:
T(n) = a*T(n/b)+c*n^k;
if (a > b^k) T(n) = O(n^(logb(a)));
if (a = b^k) T(n) = O(n^k*logn);
if (a < b^k) T(n) = O(n^k);
一、给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中一32位整数。
1、如果有足够的内存,如何处理?
2、如果内存不足,可以放在几个临时文件中,内存仅可以用几百字节来进行处理,如何处理?
答案:
1、采用位数思想来存放,32位数需要2^32个位,2^23是1MB,则一共需要2^9,即512MB的内存。
3、内存不足,可以采用如下思想:
1、按最高位分为两段,没有出现的那个数,肯定在比较小的段里面。
如果比较少的段最高位为1,那么缺少的那个数的最高位也为1.
如果比较少的段最高位为0,那么少的那个数的最高位也是0.
依次按以上方法去处理每个位。
测每个整数的每个bit是0还是1,读取n=40亿个整数,第1个bit为0或为1的放到不同的文件中(每个至多为n/2亿),少于N/2个数的那组 必定缺少某个数,接着探测第2个bit是0还是1,输入至多n/2亿,输出至多n/4亿,少于N/4个数的那组 必定缺少某个数,以此类推,总的运行时间和n成正比。通过对某组排序扫描可以得到缺失的数,这样运行时间变为o(logn)。
二、将一个n元一维向量向左旋转(循环左移)i个位置,能否仅适用数十个额外字节存储空间,在O(n)的时间内完成
1. 将a[0] 放在临时数b里,将a[i]移到a[0],a[2i]移到a[i], 再b放到a[n-i]中,如此,再对a[1]进行处理,直到所有元素都一定为止。这种方法所耗时间为n
2. 比较巧妙,分析题意,实际上是将ab反转成ba,则考虑将b分成cd两部分,d与a的长度相等。将d与a进行互换,问题转化成把dca变成cda,如此递归计算。时间复杂度也为n
3. 根据上一个方法进行改进,要将ab变成ba,假设有一个反转函数,可以对一个数组进行反转。arbr,之后再对整个进行一次反转(arbr)r就得到了ba。整个算法时间复杂度为2n,但是它的优势在于代码短,不容易出错。
三、给定一个英语字典,找出其中变位词集合,例如“stop”、“pots”、“tops”互为变位词
1. 要找到所有的变位词,如果一个一个比对,耗时太长。对每一个词产生一个额外的标志,这个标志是这个词按照字母顺序排列的结果(可使用计数排序),“stop” 为opst,“pots”也为opst