8. 给定一个具有n个元素的实数集、一个实数t以及一个整数k,请问你如何快速地确定该实数集是否存在一具有k个元素的子集,其中各元素的总和至多只能为t。
解:
利用寻找最小k元素,找到第k小的元素,然后将其前k个数相加的和与t比较即可。寻找最小k元素代码如下:
int partition(int *arr, int from, int to) {
int low = from;
int high = to;
int pivot_key = arr[low];
while(low < high) {
while(low < high && arr[high] >= pivot_key) {
--high;
}
arr[low] = arr[high];
while(low < high && arr[low] <= pivot_key) {
++low;
}
arr[high] = arr[low];
}
arr[low] = pivot_key;
return low;
}
int find(int *arr, int k, int from, int to) {
int p = partition(arr, from, to);
if(p < k - 1){
return find(arr, k, p + 1, to);
} else if(p > k - 1){
return find(arr, k, from, p - 1);
}
return arr[p];
}
9. 顺序查找和二分查找代表了查找事件和预处理时间之间的一种权衡。在具有n个元素的表中,需要执行多少次二分查找才能弥补对表进行排序时所需要的与处理时间?
解:
顺序排序时间代价:
O(n)
二分查找排序时间:
O(nlog(n))
二分查找时间代价:
O(log(n))
所以所需查找次数:
O(nlog(n)/(n−log(n)))
10. 在一位新研究员报到为托马斯爱迪生做事的那一天,爱迪生要他计算一个空电灯泡壳的体积。这位新雇员使用测径器和微积分算了几个小时之后,得到的答案是150立方厘米,没过几秒钟,爱迪生就算出了“接近155立方厘米”的答案,他是怎么做到的呢?
解:
放到水里