問題:
給定兩個有序數組a,b,長度都為n,求解兩個有序數組中第K大的數。
分析:
對於所有的這種問題,我們首先想到縮減問題的規模,但是縮減後,求解對象依舊不變,保持一致性,我們首先找到彼此的中位元,判斷中位元之間的大小,設a的中位元為x,b的中位元為y,如果x+y>k,那麼所有b中的y和大於y的數都大於k,刪除不影響問題規模;如果x+y<k,那麼刪除a中x和x之前的數字,並且將k減小到k-x,在剩餘中尋找第k-x大的數字,遞迴尋找下去。
代碼如下:
/* * findMedian.cpp * * Created on: 2012-10-28 * Author: happier */#include <stdio.h>#include <stdlib.h>#define N 5int a[N] ={ 1, 2, 3, 4, 5 };int b[N] ={ 4, 5, 6, 7, 8 };//擷取數組a中從s1到n1個元素//數組b中s2到n2個元素,合并後的第k大元素int getMedian(int s1, int n1, int s2, int n2, int k){//x和y分別記錄中間值的索引int x, y;x = (s1 + n1) / 2; //記錄a的中位元索引y = (s2 + n2) / 2; //記錄b的中位元索引if (s1 > n1)return b[s2 + k - 1];if (s2 > n2)return a[s1 + k - 1];if (a[x] <= b[y]){if (k <= (x - s1) + (y - s2) + 1){return getMedian(s1, n1, s2, y - 1, k);}else{return getMedian(x + 1, n1, s2, n2, k - (x - s1) - 1);}}else{if (k <= (x - s1) + (y - s2) + 1){return getMedian(s1, x - 1, s2, n2, k);}else{return getMedian(s1, n1, y + 1, n2, k - (y - s2) - 1);}}return 0;}int main(){int i;i = getMedian(0, 4, 0, 4, 8);printf("%d\n", i);return 0;}
代碼轉自網友
總結:
問題規模減小,但是注意修改子問題。