《编程之美》阅读分享
我阅读的课外书籍是《编程之美》,《编程之美》是一本很好的书,作者试图从书中各种有趣的问题出发,引导读者发现问题,分析问题,解决问题,寻找更优的解法。在阅读过程中,加深了我对代码的认识,充分享受到了学习和编程的乐趣。以下是我在学习过程中遇到的问题与探索:
1、在买书问题中,采取什么样的贪心算法最优?
答:本次选择的书的数量不应该小于下一次可选择的书的最大数量;
每一次选择之前都应该查表,选择其中使得近两次折扣数最大的那个作为本次选择。
2、当数据量很大时,有很多无序的数,从中找出最大的K个数。
答:用容量为K的最小堆来存储最大的K个数。最小堆的堆顶元素就是最大K个数中的最小的一个。每次扫描一个数据X,如果X比堆顶元素Y小,则不需要改变原来的堆,因为这个元素比最大的K个数要小。如果X比堆顶元素大,那么用X替换堆顶元素Y,在替换之后,X可能破坏了最小堆的结构,需要调整堆来维持堆的性质。调整过程时间复杂度为O(logK)。
3、快速找出机器故障问题的优化解法
答:1、利用异或运算。事实上,将这个列表中的所有ID异或后的值即为所求ID。这种方法时间复杂度为O(N),空间复杂度为O(1)。在时间和空间上,基本已经达到最优。
2、利用“不变量”。所有ID的和为一个不变量,对剩下ID求和。所有ID的和与剩下ID的和之差即为所求ID。由于所有ID之和可以事先算好,所以,该方法也可以在O(N)时间, O(1)空间内解决。
4、队列中取最大值操作问题的其他解法
答:用最大堆来维护队列中的节点,队列用单链表表示,每个节点包含数据,而最大堆用数组表示,数组元素为节点的指针。入队的时间复杂度为O(logn),出队的时间复杂度为O(n),达不到书上的O(logn),取最大值的时间复杂度为O(1)。
5、如果需要找出N个数组中第二大数,需要比较多少次?
- int FindSecondMax(int A[],int size)
- {
- int i=0;
- int Max = A[0];
- int secondMax;
- for(i=1;i<size;i++)
- {
- if(Max <= A[i])
- {
- secondMax = Max;
- Max= A[i];
- }
- else
- {
- if(secondMax <=A[i])
- {
- secondMax = A[i];
- }
- }
- }
- return secondMax;
- }
该算法的时间复杂度为O(N)。