LeetCode 4 - Median of Two Sorted Arrays
題目
題目連結:https://leetcode.com/problems/median-of-two-sorted-arrays/
給定兩個排序好的序列 nums1 和 nums2,長度分別為 m 和 n。
找到兩個序列的中位數。
範例說明
Example 1
1  | nums1 = [1, 3]  | 
Example 2
1  | nums1 = [1, 2]  | 
想法
我們先將題目想成從兩個序列中求出第 k 大的數字。
題目要求時間複雜度為 O(log(m + n)),所以我們首先想到如果能每一次都捨去總長度一半的序列,那我們的最終時間複雜度就會是 O(log(m + n))。
那我們要如何知道哪段序列是可以捨去的呢?
假設 nums1 以及 nums2 都是從索引值 0 開始編號。
我們比較任意 nums1[i] 以及 nums2[j],如果 nums1[i] < nums2[j],那 nums1[i] 最大的可能性為第 i + j + 1 大(如果 nums1[0] ~ nums1[i - 1], nums2[0] ~ nums2[j - 1] 都小於 nums1[i])。反之亦然,如果 nums1[i] > nums2[j],那 nums2[j] 最大的可能性也是第 i + j + 1 大。
也就是:
nums1[i] < nums2[j],nums1[i]最大為第i + j + 1大。nums1[i] >= nums2[j],nums2[j]最大為第i + j + 1大。
知道了這個性質後,如果我們取 i = k / 2 - 1 且 j = k / 2 - 1,那上述兩點會變為:
nums1[i] < nums2[j],nums1[i]最大為第k - 1大。nums1[i] >= nums2[j],nums2[j]最大為第k - 1大。
也就是說,如果 nums1[i] < nums2[j],我們可以捨去 nums1[0] ~ nums1[i],因為 nums1[i] 至多才第 k - 1 大而已。捨去後部分序列後,我們要找的變成剩下的序列中第 k - 捨去的數字數量 大的數字。
最後,如果一序列已被完全捨棄,那答案必定是另一個序列的第 k 大數字。或是當 k 剩下 1 時,我們知道答案為兩個序列的第一個數字的最小值。
因為我們每次都捨去至少 k / 2 個數字,所以 k 每次都會變小一半,直到 k = 1 為止,所以時間複雜度為 O(log(k))。而 k = m + n / 2,所以總時間複雜度為 O(log(m + n / 2)) = O(log(m + n))。
實作細節
arr1 為 nums1 之序列指標;arr2 為 nums2 之序列指標。
m 為 arr1 當前之長度,n 為 arr2 當前之長度。
若要刪除 arr1[0] ~ arr1[i - 1],則將指標向後移動 i 格,將序列長度 m 減少 i,將 k 減去 i。
程式碼
1  | /**  |