摘要:
恰当安排可以减少比较次数,见下。求序列中最大数和最小数的时候,naive的做法(分别求)需要比较大约2n次。更好的做法是:假设易知max和min是前k个元素的最大和最小,那么,将k+1与k+2先比较一下,然后,大的和max比,得到新的最大;小的和max比,得到新的最小。这样,每向后走两个元素,只需要三次比较,最终的比较次数大约是3n/2次。求序列中最大的两个数,可以这么做:假设max1, max2是一个子集A的最大和次大元素,max3, max4是另一个子集B的最大和次大元素,那么,Union(A, B)的最大元素只可能是max1和max3中比较大的一个,假设max1>max3,那么次大 阅读全文
摘要:
qsort的每一趟中,选定pivot以后,partition的过程如下:开始时,ptrLeft,ptrRight分别指向数组两端;*ptrLeft小于pivot时,向右走;*ptrRight大于pivot时,向左走;ptrLeft和ptrRight都走不动的时候,交换对应的元素,继续。ptrLeft和ptrRight相遇的时候,结束这一趟,然后二分的对两边继续qsort。更新:这样的做法需要处理各种特殊情况(略),因此更好的思路是:partition的时候,思路是:1,将pivot放到序列末尾;2,两个指针ptr_old_curr、ptr_new_curr从左向右扫描,如果*ptr_old_c 阅读全文
摘要:
实质都在于找到相应的递推关系。对于n种物体k1-kn,大小为K的背包问题来说,递推关系是:P(n, K) = P(n-1, K) || P(n-1, K-kn),也即,根据当前物体kn是不是被选中,来二分。对于树的直径问题,记f(t)为以节点t为根的子树的直径,h(t)为以节点t为根的子树的高度,则f(t) = max{ f(left), f(right), h(left) + h(right) + 2 }对于叶子节点,f与h均为0,则递归关系找到了。对于集合的划分问题(一个整数集合,是否存在一种划分,使得两个子集合中元素的和相等),立刻可以转化为背包问题。 阅读全文