問題描述
設x[ 0 : n - 1]和y[ 0 : n – 1 ]為兩個陣列,每個陣列中含有n個已排好序的數。找出x和y的2n個數的中位數。
程式設計任務
利用分治策略試設計乙個o (log n)時間的演算法求出這2n個數的中位數。
資料輸入
由檔案input.txt提供輸入資料。檔案的第1行中有1個正整數n(n<=200),表示每個陣列有n個數。接下來的兩行分別是x,y陣列的元素。
實現提示
比較兩個序列的中位數大小,如果兩個數相等,則該數為整個2n個資料的中位數,否則通過比較,分別減少兩個序列的查詢範圍,確定查詢的起止位置,繼續查詢。
結果輸入輸出
輸入檔案
輸出檔案
①這道題下午想了有挺久,首先很容易想到如果兩個陣列中間兩個數相等,那中位數就是中間那個數。這個可以舉例,如果n是奇數,如果n是偶數,發現都是滿足要求的。但是如果直接證的話,也得分如果n是奇數,那麼a陣列中中小於xa的有(n-1)/2個,大於xa的也有(n-1)/2個,同理b陣列也是,所以對於xa或者是yb則整個2n陣列中小於和大於他們的數分別為(n-1)個,取這兩個數的平均值(xa+yb)/2=xa=yb即為中位數。n是偶數,也差不多這麼證。
②但如果兩個陣列中間兩個數不等的話,如果a陣列中位數小於b陣列中位數的話,那兩個陣列合併之後的中位數一定在a的右邊或者b的左邊我感覺這其實細細品一下就出來了,然後分奇偶再討論一下,或者舉出例項,在n是奇數或是偶數的時候該怎麼分。感覺舉例項是最容易理解的
③如果a陣列中位數大於b陣列中位數的話,就跟第二種情況相反了~
#include
#include
int a[
200]
,b[200];
double
findonemiddle
(int a,
int left,
int right)
intmax
(int a,
int b)
//返回max值
intmin
(int a,
int b)
//返回min值
double
findmiddle
(int a,
int aleft,
int aright,
int b,
int bleft,
int bright)
//兩個陣列中位數相同 那麼這個中位數就是以前陣列中位數
if(mida==midb)
else
if(mida>midb)
//a左半部分 b右半部分
else
}else
if(mida
//a右半部分 b左半部分
else
}return result;
}int
main()
for(i=
0;i)fclose
(in);}
else
printf
("輸入檔案開啟失敗!\n");
double result=
findmiddle
(a,0
,n-1
,b,0
,n-1);
if((ou=
fopen
("d:\\output.txt"
,"w"))
!=null
)else
printf
("輸出檔案開啟失敗!\n");
return0;
}
自己測試了幾組資料,應該是沒問題。
下午舉了這幾組例子
①81 2 3 4 4 5 6 7
2 3 4 5 5 6 7 8
②81 2 3 4 5 6 7 8
2 3 4 5 6 7 8 9
③71 2 3 4 5 6 7
2 3 4 5 6 7 8
這三組資料應該囊括了所有情況,
先把這三組資料自己拆分,求一下,第①組第一步a陣列拆成4 5 6 7,b陣列拆成2 3 4 5
自己寫程式的時候基本就是先理解然後根據例項寫的。**感覺有點贅餘~~
兩個有序陣列中位數
大小m和n分別有兩個排序陣列a和b。找到兩個排序陣列的中值。總的執行時間複雜度應該是o log m n class solution return findkth a,b,0,0,m,n,s 2 findkth a,b,0,0,m,n,s 2 1 2 private double findkth v...
兩個有序陣列中位數
首先我們可以不斷分割得到這個kkk。首先兩個陣列都分配k 2 frac 2k 如果第k 2 frac 2k 個數,第乙個陣列小於第二個陣列,那麼第乙個陣列的k 2 frac 2k 個數一定不是答案。問題可以變成乙個子問題,上乙個陣列從k2 1 frac 1 2k 1開始。相當於我們每次要去掉k 2 ...
尋找兩個正序陣列的中位數 分治
力扣的困難題極其簡單!給定兩個大小為 m 和 n 的正序 從小到大 陣列 nums1 和 nums2。請你找出並返回這兩個正序陣列的中位數。高階 你能設計乙個時間複雜度為 o log m n 的演算法解決此問題嗎?示例 1 輸入 nums1 1,3 nums2 2 輸出 2.00000 解釋 合併陣...