LeetCode:4_Median of Two Sorted Arrays | 求兩個排序數組的中位數 | Hard


題目:

 

There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Subscribe to see which companies asked this question

解題思路:

  我自己想的方法,先排序在查找。兩個數組,首先想到是歸並排序,然后再查找兩個數組合並之后的中間元素即為中位數。我們分析下時間復雜度主要用在了歸並排序上,為O((m+n)log(m+n)),顯然不符合題目要求。題目要求是O(log(m+n)),但是我將這個方法的代碼提交上去,仍然通過了,說明LeetCode的編譯平台並沒有嚴格按照ACM OJ這種要求來設置。排序后查找的代碼如下所示:

 1 //方法一:歸並排序后查找:O((m+n)lg(m+n)),奇怪竟然通過了
 2 double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2)
 3 {
 4     size_t n1 = nums1.size(), n2 = nums2.size();
 5     size_t n = n1+n2;
 6     vector<int> nums(n,0);
 7 
 8     assert(n > 0);
 9     
10     nums1.push_back(INT_MAX);
11     nums2.push_back(INT_MAX);
12 
13     size_t i = 0, j = 0, k = 0;
14     while(i < n1 || j < n2) {
15         if (nums1[i] <= nums2[j]) {
16             nums[k++] = nums1[i++];
17         }
18         else
19             nums[k++] = nums2[j++];
20     }
21 
22     return ((n%2) ? (double)nums[(n-1)/2]:(double)(nums[(n-1)/2]+nums[n/2])/2);
23 }

  

  看了下本題的難度系數,屬於Hard級別的,說明本題不是那么容易對付的,又看了一下本題的Tag,其中羅列了兩個重要的Tag:Divide and Conquer和Binary Search,說明本題需要用到兩個方法:分治法和二分查找法,看了討論里面,發現一種方法是這樣的:求有序數組A和B有序合並之后第k小的數!如果A[k/2-1]<B[k/2-1],那么A[0]~A[k/2-1]一定在第k小的數的序列當中,可以用反證法證明。詳細的思路請見這篇博文。代碼如下:

 1 //方法二:二分法:O(lg(m+n)),滿足題目要求
 2 //get the kth number of two sorted array
 3 double findkth(vector<int>::iterator a,int m,
 4                vector<int>::iterator b,int n,
 5                int k)
 6 {
 7     if(m >  n)
 8         return findkth(b,n,a,m,k);
 9     if(m == 0)
10         return b[k-1];
11     if(k == 1)
12         return min(*a,*b);
13 
14     int pa = min(k/2,m),pb = k - pa;
15     if(*(a + pa - 1) < *(b + pb -1))
16         return findkth(a+pa,m-pa,b,n,k-pa);
17     else if(*(a + pa -1) > *(b + pb -1))
18         return findkth(a,m,b+pb,n-pb,k-pb);
19     else
20         return *(a+pa-1);
21 }
22 
23 double findMedianSortedArrays1(vector<int>& nums1, vector<int>& nums2) {
24     vector<int>::iterator a = nums1.begin();
25     vector<int>::iterator b = nums2.begin();
26     int total = nums1.size() + nums2.size();
27 
28     // judge the total num of two arrays is odd or even
29     if(total & 0x1)
30         return findkth(a,nums1.size(),b,nums2.size(),total/2+1);
31     else
32         return (findkth(a,nums1.size(),b,nums2.size(),total/2) + findkth(a,nums1.size(),b,nums2.size(),total/2 + 1))/2;
33 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM