聲明:
使用C語言,結合函數 double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) 詳細說明
解題思路:
一個長度爲 nums1Size 的數組,0 到 nums1Size 總共有 nums1Size 個位置可以切Cut
比如說 nums1Size = 3 :
我們把數組 nums1 和 nums2 分別在 i 和 j 位置上切割
i 的左邊和 j 的左邊組成左半部分, i 的右邊和 j 的右邊組成右半部分。左半部分的長度等於右半部分
i的初始位置爲 num1Size/2
i+j=nums1Size-i+nums2Size-j => j=(nums1Size+nums2Size)/2-i
+1是將兩個數組總長度是奇數情況下考慮進去,兩個數組總長度是奇數時,左半部分的長度等於右半部分加1。
因爲我們取的是int值,不影響上述結果。
j=(nums1Size+nums2Size+1)/2-i
以下分爲兩種情況討論:
當 nums2[ j - 1 ] > nums1[ i ] 時,i 需要向右移,即 i 增大
當 nums1[ i - 1 ] > nums2[ j ] 時,i 需要向左移,即 i 減小
兩種情況 j 會隨着 i 變化而變化。
直到滿足條件 "左半部分最大的值小於等於右半部分最小的值 max( nums1[ i - 1 ] , nums2[ j - 1 ] ) <=
min( nums1[ i ], nums2[ j ] ) " 進行以下討論。
i 切到邊界(0或nums1Size)情況下,
當 i = 0 時,左半最大值 = nums2[ j - 1 ]。
當 i = nums1Size 時,右半最小值 = nums2[ j ]。
j 切到邊界亦是如此;
當兩個數組總長度是奇數時,中位數來自 max( nums1[ i - 1 ] , nums2[ j - 1 ]),即左半最大值。
當兩個數組總長度是偶數時,中位數來自 [ max( nums1[ i - 1 ], nums2[ j - 1 ] ) + min( nums1[ i ], nums2[ j ] ) ] / 2,也就是左半部分的最大值加右半部分最小值除於2。
本人github:https://github.com/Tomy-Enrique/LeetCode
以下代碼參考:
#include <iostream>
//#include <algorithm>
using namespace std;
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
if(nums1Size > nums2Size){ //保證數組1一定最短
return findMedianSortedArrays(nums2, nums2Size, nums1, nums1Size);
}
int iMin = 0, iMax = nums1Size;
int maxLeft = 0, minRight = 0;
while (iMin <= iMax)
{
//i爲第一個數組的割,j爲第二個數組的割
int i = (iMin + iMax) / 2;
int j = (nums1Size + nums2Size + 1) / 2 - i;
//cout << i << " "<< j << endl;
if(j != 0 && i != nums1Size && nums2[j-1] > nums1[i]){ //i需要增大
iMin = i+1;
}
else if(i != 0 && j != nums2Size && nums1[i - 1] > nums2[j] ){ //i需要減小
iMax = i-1;
}
else{ //滿足條件 max(nums1[i-1], nums2[j-1]) <= min(nums1[i], nums2[j])
if(i == 0){
maxLeft = nums2[j-1];
}
else if(j == 0){
maxLeft = nums1[i-1];
}
else{
maxLeft = nums1[i-1] > nums2[j-1] ? nums1[i-1] : nums2[j-1];
}
if(i == nums1Size && j == nums2Size){
minRight = 0;
}
else if(i == nums1Size){
minRight = nums2[j];
}
else if(j == nums2Size){
minRight = nums1[i];
}
else{
minRight = nums1[i] > nums2[j] ? nums2[j] : nums1[i];
}
if((nums1Size + nums2Size) % 2 == 1){
return maxLeft;
}else{
return (maxLeft + minRight) / 2.0;
}
}
}
return 0.0;
}
int main()
{
int nums1[4] = {2, 3, 5, 6};
int nums2[4] = {1, 4, 7, 9};
int nums3[2] = {1, 2};
int nums4[2] = {-1, 3};
cout << findMedianSortedArrays(nums3, 2, nums4, 2);
}