leetcode-4:Median of Two Sorted Arrays

题目

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)).
You may assume nums1 and nums2 cannot be both empty.

Example 1:

nums1 = [1, 3]
nums2 = [2]
The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5

思路 O(log(min(m,n))

       left_part             |        right_part
    A[0], A[1], ..., A[i-1]  |  A[i], A[i+1], ..., A[m-1]
    B[0], B[1], ..., B[j-1]  |  B[j], B[j+1], ..., B[n-1]

找到 i,j 使得  条件1满足:

even:  size(left_part)+size(right_part)=i+j =(m+n)/2

odd:    size(left_part)+size(right_part)=i+j =(m+n+1)/2

&&

A[i-1]\leq B[j]

B[j-1]\leq A[i]

这时,就有

even:  median = max(A[i-1], B[j-1]) + min(A[i],B[j])/2

odd:    median = max(A[i-1], B[j-1])

特殊情况  m< n

i=m
       left_part               |        right_part
    A[0], A[1], ..., A[m-1]    |  
    B[0], B[1], ..., B[j-1]    |  B[j], B[j+1], ..., B[n-1]

even:   median = (B[j-1]+B[j])/2

odd:     median = B[j-1]

i=0
       left_part             |        right_part
                             |  A[0], A[1], ...,   A[m-1]
    B[0], B[1], ..., B[j-1]  |  B[j], B[j+1], ..., B[n-1]

even:   median = (B[j-1]+B[j])/2

odd:     median = B[j-1]

特殊情况 m=n

j=n

j=n
       left_part             |        right_part
                             |  A[0], A[1], ...,   A[m-1]
    B[0], B[1], ..., B[n-1]  | 

even:   median = (B[n-1]+A[0])/2


j=0

j=0
       left_part             |        right_part
    A[0], A[1], ..., A[m-1]  |  
                             |  B[0], B[1], ..., B[n-1]

even:   median = (B[0]+A[m-1])/2

接下来的问题是如何找到合适的 i ,j,根据 size(left_part)+size(right_part)=i+j =(m+n+1)/2 可以得到i,j之间约束,此时j=(m+n+1)/2-i,而约束n>=m的意义就在于对于任何i,j都在[0,n]得区间内。因此在[0,m] 闭区间上搜索i,使得 A[i-1]\leq B[j] \&\& B[j-1]\leq A[i]  满足。

不考虑  size(left_part)+size(right_part)=i+j =(m+n)/2  是因为 当m+n是偶数时,(int)(m+n)/2 = (int)(m+n+1)/2

对于任意一个 i\subseteq (0,m),有以下3种情况

  • A[i-1]> B[j]   ,说明 i 太大 ,i应该比当前值要小,减小A[i-1]的值,同时根据j=(m+n+1)/2-i ,j增大,增大B[j],并且搜索区间减少为(0,i)
  • B[j-1]> A[i]   ,说明 i 太小 ,i应该比当前值要大,并且搜索区间减少为(i,m)
  • 其他情况,就是找到合适的i,j

使用二分法,设定初始区间为[imin,imax]=[0,m],判断值为区间中值 i= (imax-imin)/2+imin

有以下情况

0<i(确保A[i-1]存在),A[i-1]> B[j]  这时使 [imin,imax]=[imin,i-1]

i<m(确保A[i]存在),B[j1]> A[i]  这时使 [imin,imax]=[i+1,imax]

其他情况就是找到合适的i,j

随着搜索区间变化,其中有两种极端的收敛情况

[imin,imax] = [0,0]  和 [imin,imax]=[m,m] 对应上面两种特殊情况,因此使用二分法并且把初始区间设定为闭区间,即可自动得到这两种结果。此时的i=0 或者 i=m,j=0或者j=n ,根据i , j可以区分出特殊情况

class Solution {
public:
	double bsearch(vector<int>& A, vector<int>& B) {
		int m = A.size();
		int n = B.size();
		int imin = 0, imax = m, half_len = (m + n + 1) / 2;
		int i, j, max_of_left, min_of_right;

		while (imin <= imax) {
			i = (imin + imax) / 2;
			j = half_len - i;
			if (i<m && B[j - 1]>A[i]) { imin = i + 1; }
			else if (i > 0 && A[i - 1] > B[j]) { imax = i - 1; }
			else {
				if (i == 0) { max_of_left = B[j - 1]; }
				else if (j == 0) { max_of_left = A[i - 1]; }
				else { max_of_left = max(A[i - 1], B[j - 1]); }

				if ((m + n) % 2 == 1) { return max_of_left; }

				if (i == m) { min_of_right = B[j]; }
				else if (j == n) { min_of_right = A[i]; }
				else { min_of_right = min(A[i], B[j]); }

				return double((max_of_left + min_of_right)) / 2;
			}
		}
	}
	double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
		int nums1_size = nums1.size();
		int nums2_size = nums2.size();
		if (nums1_size > nums2_size) {return bsearch(nums2, nums1);}
		else { return bsearch(nums1, nums2); }
	}
};

猜你喜欢

转载自blog.csdn.net/qq_25379821/article/details/82491479
今日推荐