高难度题
18.1 编写一个函数,将两个数字相加。不得使用+或其他算术运算符。(第 105 页)
18.2 编写一个方法,洗一副牌。要求做到完美洗牌,换言之,这副牌 52!种排列组合出现 的概率相同。假设给定一个完美的随机数发生器。(第 106 页)
利用简单构造法,我们不妨先问问自己:假定有个方法shuffle(...)对n 1个元素有效, 我们可以用它来打乱n个元素的次序吗? 当然可以,而且非常容易实现。我们会先打乱前n 1个元素的次序,然后,取出第n个元素, 将它与数组中的元素随机交换。就这么简单!
18.3 编写一个方法,从大小为n的数组中随机选出m个整数。要求每个元素被选中的概率 相同。(第 106 页)
与18.2类似,我们可以利用简单构造法,以递归方式处理此题
18.4 编写一个方法,数出 0 到n(含)中数字 2 出现了几次。(第 106 页)
- 蛮力解法
18.6 设计一个算法,给定 10 亿个数字,找出最小的 100 万个数字。假定计算机内存足以 容纳全部 10 亿个数字。(第 106 页)
此题有很多种解法,下面将介绍其中三种:排序、小顶堆和选择排序(selection rank)。
我们可以使用小顶堆来解题。首先,为前100万个数字创建一个大顶堆(最大元素位于堆顶)。 然后,遍历整个数列,将每个元素插入大顶堆,并删除最大的元素。 遍历结束后,我们将得到一个堆,刚好包含最小的100万个数字。这个算法的时间复杂度为 O(n log(m)),其中m为待查找数值的数量。
随机生成一些数字并传入某个方法。编写一个程序,每当收到新数字时,找出并记 录中位数。(第 106 页)
是使用两个优先级堆(priority heap)
18.10 给定两个字典里的单词,长度相等。编写一个方法,将一个单词变换成另一个单词, 一次只改动一个字母。在变换过程中,每一步得到的新单词都必须是字典里存在的。(第 106 页)
给定一个正整数和负整数组成的N×N矩阵,编写代码找出元素总和最大的子矩阵。 (第 106 页)
???
18.13 给定一份几百万个单词的清单,设计一个算法,创建由字母组成的最大矩形,其中 每一行组成一个单词(自左向右),每一列也组成一个单词(自上而下)。不要求这些单词在清单 里连续出现,但要求所有行等长,所有列等高。(第 106 页)