1. 程式人生 > 實用技巧 >【LeetCode】4. Median of Two Sorted Arrays(思維)

【LeetCode】4. Median of Two Sorted Arrays(思維)

【題意】

給兩個有序陣列,尋找兩個陣列組成後的中位數,要求時間複雜度為O(log(n+m))。

【題解】

感覺這道題想法非常妙!!

假定原陣列為a,b,陣列長度為lena,lenb。

那麼中位數一定是第k = (lena + lenb + 1)/ 2小的數,如果是陣列長度和是偶數的話就是第k = (lena + lenb + 1)/ 2小和第k = (lena + lenb + 2)/ 2小的數,所以我們可以把問題轉化為求第k小的數。

然後分別對a,b找第k / 2小的數,假如a[k / 2 - 1]和b[k / 2 -1] ,如果a[k / 2 - 1 > b[k / 2 - 1],那麼就說明b[k / 2 - 1]必然不是我們要找到的答案,也就是說k / 2 - 1之前的數字我們都可以排除掉,下一次b陣列的開始位置變成k / 2,然後下一次就要尋找第k = k - (k / 2)小的數(此處預設從0開始)了,然後不斷遞迴,直到k = 1,也就是說當前指向的數就是我們要找的數,這時只要取兩者最小值即可。

【程式碼】

 1 class Solution {
 2 public:
 3     double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
 4         int len1 = nums1.size();
 5         int len2 = nums2.size();
 6         int k1 = (len1 + len2 + 1) / 2;
 7         int k2 = (len1 + len2 + 2) / 2;
 8         double
ans = (findk(0, len1 - 1, nums1, 0, len2 - 1, nums2, k1) * 1.0 + findk(0, len1 - 1, nums1, 0, len2 - 1, nums2, k2) * 1.0) / 2; 9 return ans; 10 } 11 int findk(int st1, int en1, vector<int>& nums1, int st2, int en2, vector<int>& nums2, int k) 12 { 13 int len1 = en1 - st1 + 1
; 14 int len2 = en2 - st2 + 1; 15 // 使nums1的長度保持小於nums2 16 if (len1 > len2) 17 return findk(st2, en2, nums2, st1, en1, nums1, k); 18 if (len1 == 0)return nums2[st2 + k - 1]; 19 if (k == 1)return min(nums1[st1], nums2[st2]); 20 21 int i = st1 + min(len1, k / 2) - 1; 22 int j = st2 + min(len2, k / 2) - 1; 23 if (nums1[i] > nums2[j]) 24 return findk(st1, en1, nums1, j + 1, en2, nums2, k - (j - st2 + 1)); 25 else 26 return findk(i + 1, en1, nums1, st2, en2, nums2, k - (i - st1 + 1)); 27 } 28 };
View Code