搜索算法可以有很多种分类方式。底层的容器是静态的还是动态的,换句话说,搜索时插入和删除是否是交错进行的?是否值得花费计算量去预处理数据以便加速后续的查询?数据是否有统计的特性可以利用的?我们应该对数据直接操作数据进行变换?
我们在此只考虑在有序数组中存储的静态数据。适用于动态更新的数据结构是堆、哈希表、和二叉搜索树的主题。
首先探讨的问题是有关二分查找,后面问题属于通用搜索。
1. 在有序数组中搜索第一个k:
给定一个有序数组和一个key,返回这个key在数组中第一次出现的index。
提示:当每一个元素都等于k时会怎么样?第一次看到k后不要停止。
2. 有序数组中搜索值与索引相等的元素:
设计一个高效的算法,给定一个无重复元素的整数有序数组,返回一个元素值与其索引相等的索引。
提示:把问题转化为普通的二分搜索。
3. 搜索一个循环有序数组:
设计一个O(logn)的算法,找到循环数组中最小元素的索引。假设所有的元素都是不同的。
提示:运用分治理论。
4. 计算整数的平方根:
给定一个非负整数,返回平方根小于等于给定整数的最大整数。
5. 计算实数的平方根:
给定一个浮点数,返回它的平方根。
提示:迭代地计算一个区间序列,每一个都包含于前面包含结果的的区间中。
6. 在2D有序数组中搜索:
如果一个二维数组的行和列都是非递减的,则称其为有序的。
给定一个二维数组和一个数字,检查这个数字是否在这个数组中。
提示:每次比较可以去掉一个行或者一个列吗?
7. 同时寻找最小与最大值:
设计一个算法找到一个数组中的最小的元素与最大的元素。
提示:如果a<b并且b<c可以推断出a<c,利用这个事实减少暴力解法比较的次数。
8. 找到第k个大的元素:
设计一个算法计算数组中第k个大的元素,假设所有元素都是不同的。
提示:随机化运用分治法。
9. 找到丢失的IP地址:
假设给定一个文件包含大约十亿个IP地址,每一个是32位。你如何编程找到一个IP地址不在文件中?假设你有无限的磁盘空间,但是只有几兆字节的内存由你支配。
提示:你能确定有一个地址不在文件中吗?
10. 找到重复的和缺失的元素:
如果一个数组包含n-1个整数,每一个整数的范围都是0到n-1(包括0和n-1),并且数组中所有数字都是不同的,所以一定只有一个元素出现两次,0到n-1之间一定只有一个数字是缺失的。怎样才能算出重复的和缺失的数字?
提示:考虑多次遍历整个数组。