PHP 兩個等長有序數組求合并後的中位元

來源:互聯網
上載者:User

演算法思路:每次取兩個數組的中位元進行比較,

我們假定取的中位元是下中位元,即每次取中位元座標時使用floor取出,當數組長度是奇數時,取得是正中間的元素,是偶數時取得就是下中位元

1. a[n/2] == b[n/2],可知中位元即為a[n/2],返回即可

2. a[n/2] < b[n/2],設a,b數組藍色紅色部分元素分別為a[b],a[r],b[b],b[r],

可知 a[b] <= a[n/2] < b[n/2] <= b[b]

於是有 a[b] <= a[r], a[b] < b[b] (數組元素可能存在重複)

b[b] >= b[r] , b[b] > a[b]

這樣我們就知道了a[b]中的元素至少小於n個元素,b[b]中的元素至少大於n個元素,易知中位元就不可能在藍色部分了

那麼排除了藍色部分以後,就可以對紅色部分重新用取中位元的方法來尋找總的中位元,直到切分後的數組只剩一個元素,我們取較小的那個元素即可

那麼在從中位元座標切分數組時,我們到底要不要把中位元元素也放入紅色部分呢?這裡有兩種情況

1)當n為奇數時,我們需要把a,b的中位元都放入紅色部分進行遞迴尋找,因為當a,b數組合并後,a[n/2] b[n/2]仍然有可能排在合并數組的正中間,那麼中位元就是二者其一

舉個例子, a = (1,3,5,7,9), b = (2,4,6,8,10),最後拍出來肯定是1,2,3,4,5,6,7,8,9,10,可見這裡5,6都是中位元

2)當n為偶數時,我們需要將較小的那個中位元排除掉,只讓他右邊的紅色部分進入遞迴尋找(這裡是排除a[n/2],如果a[n/2] > b[n/2],則排除b[n/2])

這是因為如果數組長度是偶數,那麼我們取的中位元肯定是下中位元,且a[n/2] < b[n/2],則數組合并以後a[n/2]肯定位於總中位元的左邊,所以a[n/2]肯定不是最後的中位元

舉個例子, a = (1,3,5,7), b = (2,4,6,8),則最後排出來是12345678,我們取的中位元是3, 4,可見3不可能是中位元,中位元是4,5

 

好了。下面看代碼

 1 <?php 2     #兩個長度皆為n的數組,兩個數組已排序,求兩個數組所有數字中的中位元 3     function get_mid($a, $b) { 4         print_r($a); 5         echo "<br>"; 6         print_r($b); 7         echo "<br>"; 8         if (count($a) == 1) { 9             $result_mid = min($a[0], $b[0]); #如果數組只剩一個元素,返回這個元素即為中位元10         } else {11             $mid = floor((count($a) - 1) / 2); #中位元座標取下中位元12             echo "mid : {$mid}<br>";13 14             #如果a[mid] == b[mid],則中位元就是mida,返回即可15             #如果a[mid] < b[mid],選擇數組a的右部,數組b的左部進入遞迴,直到最後遞迴部分數組長度為116             #如果a[mid] > b[mid],選擇數組a的左部,數組b的右部進入遞迴,直到最後遞迴部分數組長度為117 18             #此處需要特別注意,當數組長度為奇數時,切分AB數組都要把中位元加上19             #但數組長度為偶數時,只需要把較大的數組的左部加上中位元,較小的數組則捨棄中位元只要右部進入遞迴20 21             if (count($a) % 2 == 0) {22                 $small_arr_start = $mid + 1;23             } else {24                 $small_arr_start = $mid;25             }26 27             if ($a[$mid] == $b[$mid]) { #兩數組中位元相等,返回中位元28                 $result_mid = $a[$mid];29             } else if ($a[$mid] < $b[$mid]) { #此處需要特別注意30                 $atemp = array_slice($a, $small_arr_start); #切分數組,較小的數組根據長度是否是奇偶捨棄中位元31                 $btemp = array_slice($b, 0, $mid + 1);32                 $result_mid = get_mid($atemp, $btemp);33             } else {34                 $atemp = array_slice($a, 0, $mid + 1);35                 $btemp = array_slice($b, $small_arr_start);36                 $result_mid = get_mid($atemp, $btemp);37             }38         }39 40         return $result_mid;41     }42 43     $a = array(1, 3, 5, 5, 7, 8, 9);44     $b = array(2, 2, 7, 8, 9, 10, 14);45 46     echo "midnum : " . get_mid($a, $b) . "<br>";47 48     array_splice($a, count($a) - 1, 0, $b);49     sort($a);50 51     print_r($a);52 ?>

 Array ( [0] => 1 [1] => 3 [2] => 5 [3] => 5 [4] => 7 [5] => 8 [6] => 9 ) 
Array ( [0] => 2 [1] => 2 [2] => 7 [3] => 8 [4] => 9 [5] => 10 [6] => 14 ) 
mid : 3
Array ( [0] => 5 [1] => 7 [2] => 8 [3] => 9 ) 
Array ( [0] => 2 [1] => 2 [2] => 7 [3] => 8 ) 
mid : 1
Array ( [0] => 5 [1] => 7 ) 
Array ( [0] => 7 [1] => 8 ) 
mid : 0
Array ( [0] => 7 ) 
Array ( [0] => 7 ) 
midnum : 7
Array ( [0] => 1 [1] => 2 [2] => 2 [3] => 3 [4] => 5 [5] => 5 [6] => 7 [7] => 7 [8] => 8 [9] => 8 [10] => 9 [11] => 9 [12] => 10 [13] => 14 )

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.