4. Median of Two Sorted Arrays

来源:互联网 发布:js atan2函数 编辑:程序博客网 时间:2024/05/16 13:46

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)).

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

中位数可以用来把一个序列划分成等长的两个序列,并且其中一个序列必然比另一个序列大。假如我们在nums1找到一个点i,在nums2找到另一个点j,保证length(nums1(0,i-1) + nums2(0, j-1)) == length(nums1(i, m) + nums2(j, n)) 并且 max(nums1(0,i-1),  nums2(0, j-1)) <= min(nums1(i, m), nums2(j, n)), 那我们就相当于把nums1和nums2组成的一个序列等长划分成两个子序列,并且保证左边的序列一定小于或等于右边的序列。也就是:

1) i+j = m - i + n - j(或者 m - i + n - j +1, 这是序列个数为基数的情况);

2) nums1[i-1] <= nums2[j] && nums2[j-1] <= nums1[i]


对于1,我们假设n>=m, 令i=(0,m), 那么j=(m+n+1)/2-i; 这么处理的原因是为了保证j有效。假设m>n && i == m, 那么j = (n+1)/2 - m/2很有可能是负数。为了保证j有效,我们需要比较两个序列的长度。

因此,这个题可以定义为,在nums1和nums2两个数组里,选较短的一个数组,找到位置i,符合条件j=(m+n+1)/2 - i 并且a[i-1] <= b[j] && b[j-1] <= a[i]. 此时,当我们使用binary search进行检索i的位置,会出现以下情况:

1)a[i-1] <= b[j] && b[j-1] <= a[i], i就是我们要找的位置

2)a[i-1] > b[j], 说明i的位置过大,i需要往左边挪令a[i-1] 变小,与此同时,i变小,j就会相应变大,b[j]也会变大,直到找到一个数令a[i-1] <= b[j];

3)b[j-1] > a[i], 说明i的位置过小,需要往右边挪令a[i]变大,与此同时,i变大,j就会变小,b[j-1]相应变小,直到找到一个数令b[j-1] <= a[i];


代码:


public class Solution {    public double findMedianSortedArrays(int[] nums1, int[] nums2) {       int[] A = nums1;       int[] B = nums2;       if(nums1.length > nums2.length) {           A = nums2;           B = nums1;       }       int m = A.length;       int n = B.length;       int imin = 0;       int imax = m;       int half = (m+n+1)/2;       while(imin <= imax) {           int i = (imin + imax)/2;           int j = half - i;           if(i-1 >= 0 && j < n && A[i-1] > B[j]) {              imax = i-1;            } else if(j -1 >= 0 && i < m && B[j-1] > A[i]) {               imin = i+1;           } else {               int maxLeft = 0;               if(i <= 0) {                   maxLeft = B[j-1];               }  else if(j <= 0) {                   maxLeft = A[i-1];               } else {                   maxLeft = Math.max(A[i-1], B[j-1]);               }               if((m+n)%2 == 1) {                   return maxLeft;               }               int minRight = 0;               if(j >= n) {                   minRight = A[i];               } else if(i >= m) {                   minRight = B[j];               } else {                   minRight = Math.min(A[i],B[j]);               }               return (maxLeft + minRight)/2.0;           }       }       return -1;    }}


0 0
原创粉丝点击