剪枝法
学自 LeetCode 题目4.寻找两个有序数组的中位数
剪枝法的思想就是将可以确定的不需要考虑的元素剪掉,每次迭代剪掉一些,直至找到最终解。
有两个有序数组:
- A0,A1…An-1
- B0,B1…Bm-1
寻找其中位数?
若将两个数组合并,则数组长度为 m+n,中位数的取值有两种情况:
- 1.n+m 为奇数,则中位数下标为 k = (m+n+1)/2;
- 2.n+m 为偶数,则中位数下标为 k = (m+n)/2,(m+n)/2-1。
因此我们只需要找到{A,B}中第k个值或者第k和k+1个值即可。
现在考虑
- A0,A1…A[k/2-1]…An-1
- B0,B1…B[k/2-1]…Bm-1
初始:k(要求的第k个值)如 k = (m+n+1)/2 或 k = (m+n)/2, k = (m+n)/2-1。
若:
- 1)A[k/2-1] <= B[k/2-1],A数组中,A[k/2-1] 的左边共有 k/2-1 个元素比它小,由于 B[k/2-1] >= A[k/2-1],因此在{A,B}中最多有k-2个值比 A[k/2-1]大,故 A 中下标 k/2 之前的都可以剪去。
- 2)A[k/2-1] > B[k/2-1],同1,不过这种情况下剪去的是B中元素。
- 3)A[k/2-1] == B[k/2-1],同1,不做其他改变。
重复上述步骤,直至k=1,min{A[0],B[0]}即为第 k 个元素。
这道题要做完,还需要考虑一些边界情况,如
- 1)A 中元素剪枝时给剪完了,则可以直接输出B[k];
- 2)B 中元素同上;
在实际实现的时候,我们需要用两个下标分别表示 A,B 中剩余元素首地址,而不是真删除它们。