分析
首先想到的方法應該是將兩個數組 nums1
和 nums2
合并成一個新的數組 arr
,在合并的過程中需要確保該新數組有序,這時候再根據新數組中包含數字的個數來求最后的結果:
- 若包含數字個數是奇數,直接取數組的中間值作為最后的結果
- 若包含數字個數是偶數,取數組最中間的兩個數字的均值作為最后的結果
顯然,生成新的數組需要遍歷兩個數組,但是其實并不需要完整的遍歷兩個數組,只需要計算遍歷的次數是兩個數組長度的均值即可,這個時候就能發現中間的值了。
解答
代碼如下:
var findMedianSortedArrays = function(nums1, nums2) {
if ( !(Array.isArray(nums1) && Array.isArray(nums2)) || (nums1.length === 0 && nums2.length === 0) ) return;
var arr = [],
mlen = nums1.length,
nlen = nums2.length,
isOdd = ( nums1.length + nums2.length )%2;
// nums1 和 nums2 中有一個是空數組,就計算并返回另一個數組的中間值
if ( mlen === 0 ) return nlen%2 ? nums2[ Math.floor(nlen/2) ] : ( nums2[nlen/2 - 1] + nums2[nlen/2] )/2;
if ( nlen === 0 ) return mlen%2 ? nums1[ Math.floor(mlen/2) ] : ( nums1[mlen/2 - 1] + nums1[mlen/2] )/2;
// 遍歷的次數為兩個數組長度的均值
while ( arr.length !== Math.floor((mlen + nlen)/2) ){
// 1. 若遍歷的過程中兩個數組中有一個空了,則彈出另一個的首值并壓入 arr 中
// 2. 兩個數組都沒有空的話,比較他們首值的大小,將較小的彈出并壓入 arr 中
if ( nums2[0] === undefined || nums1[0] <= nums2[0] ){
arr.push( nums1.shift() );
} else {
arr.push( nums2.shift() );
}
}
// 遍歷結束后兩個數組中有一方變成空數組的情況
// 奇數,那么剩下的非空數組的首值就是最后的結果
// 偶數,那么剩下的非空數組額首值與 arr 的末值的均值就是最后的結果
if ( nums1[0] === undefined ) return isOdd ? nums2[0] : (nums2[0] + arr[arr.length - 1])/2;
if ( nums2[0] === undefined ) return isOdd ? nums1[0] : (nums1[0] + arr[arr.length - 1])/2;
// 遍歷結束后兩個數組均非空的情況
// 奇數,兩個數組首值的較小值就是最后的結果
// 偶數,兩個數組首值的較小值與 arr 末值的均值就是最后的結果
if ( isOdd ){
return nums1[0] < nums2[0] ? nums1[0] : nums2[0];
} else {
return nums1[0] < nums2[0] ? (nums1[0] + arr[arr.length-1])/2 : (nums2[0] + arr[arr.length - 1])/2;
}
};