zoukankan      html  css  js  c++  java
  • 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)).

    The first solution could be generalized to Find the Kth value in 2 sorted arrays.

     1 Solution 1. Divide and Conquer, Recursion
     2 public class Solution {
     3     public double findMedianSortedArrays(int A[], int B[]) {
     4         int m = A.length;
     5         int n = B.length;
     6         int total = m+n;
     7         if((total & 0x1)==1) {
     8             return findKth(A, 0, m, B, 0, n, total/2+1);
     9         } else {
    10             return (findKth(A, 0, m, B, 0, n, total/2)+findKth(A, 0, m, B, 0, n, total/2+1))/2.0;
    11         }
    12     }
    13     public double findKth(int[] A, int s1, int t1, int[] B, int s2, int t2, int K) {
    14         if(t1-s1>t2-s2) return findKth(B, s2, t2, A, s1, t1, K);
    15         if(t1-s1==0) return B[s2+K-1];
    16         if(K == 1) return Math.min(A[s1], B[s2]);
    17         
    18         int anum = Math.min(K/2+s1, t1);
    19         int bnum = K - anum + s1 + s2;
    20         if(A[anum-1]>B[bnum-1]) {
    21             return findKth(A, s1, anum, B, bnum, t2, K-bnum+s2);
    22         } else {
    23             return findKth(A, anum, t1, B, s2, bnum, K-anum+s1);
    24         }
    25     }
    26 }

    The second solution convert the problem to make it clear as a Divide and Conquer problem -- "Find a specific value satisfied some conditions in an array"

    Refer to https://leetcode.com/discuss/15790/share-my-o-log-min-m-n-solution-with-explanation
    To solve this problem, we need to understand "What is the use of median". In statistics, the median is used for dividing a set into two equal length subsets, that one subset is always greater than the other. If we understand the use of median for dividing, we are very close to the answer. First let's cut A into two parts at a random position i: left_A | right_A A[0], A[1], ..., A[i-1] | A[i], A[i+1], ..., A[m-1] Since A has m elements, so there are m+1 kinds of cutting( i = 0 ~ m ). And we know: len(left_A) = i, len(right_A) = m - i . Note: when i = 0 , left_A is empty, and when i = m , right_A is empty. With the same way, cut B into two parts at a random position j: left_B | right_B B[0], B[1], ..., B[j-1] | B[j], B[j+1], ..., B[n-1] Put left_A and left_B into one set, and put right_A and right_B into another set. Let's name them left_part and right_part : 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] If we can ensure: 1) len(left_part) == len(right_part) 2) max(left_part) <= min(right_part) then we divide all elements in {A, B} into two parts with equal length, and one part is always greater than the other. Then median = (max(left_part) + min(right_part))/2. To ensure these two conditions, we just need to ensure: (1) i + j == m - i + n - j (or: m - i + n - j + 1) if n >= m, we just need to set: i = 0 ~ m, j = (m + n + 1)/2 - i (2) B[j-1] <= A[i] and A[i-1] <= B[j] (For simplicity, I presume A[i-1],B[j-1],A[i],B[j] are always valid even if i=0/i=m/j=0/j=n . I will talk about how to deal with these edge values at last.) So, all we need to do is: Searching i in [0, m], to find an object `i` that: B[j-1] <= A[i] and A[i-1] <= B[j], ( where j = (m + n + 1)/2 - i )
     1 public class Solution {
     2     public double findMedianSortedArrays(int[] nums1, int[] nums2) {
     3         if (nums1.length > nums2.length) return findMedianSortedArrays(nums2, nums1);
     4         
     5         int m = nums1.length, n = nums2.length;
     6         int K = (m + n + 1) / 2;
     7         
     8         double ret1 = 0.0, ret2 = 0.0;
     9         int amin = 0, amax = nums1.length;
    10         
    11         // include amin, exclude amax, when nums1.length==0, this still work
    12         while (amin <= amax) {
    13             int aidx = (amax - amin) / 2 + amin;
    14             int bidx = K - aidx;
    15             if (aidx > 0 && bidx < n && nums1[aidx-1] > nums2[bidx]) {
    16                 // in case m == n and aidx == 0 --> bidx == n
    17                 amax = aidx-1;
    18             } else if (bidx > 0 && aidx < m && nums1[aidx] < nums2[bidx-1]) {
    19                 // in case m == n and aidx == m --> bidx == 0
    20                 amin = aidx+1;
    21             } else {
    22                 // nums1[aidx] > nums2[bidx-1] && nums2[bidx] > nums1[aidx-1]
    23                 if (aidx == 0) {
    24                     ret1 = (double) nums2[bidx-1];
    25                 } else if (bidx == 0) {
    26                     ret1 = (double) nums1[aidx-1];
    27                 } else {
    28                     ret1 = (double) Math.max(nums1[aidx-1], nums2[bidx-1]);
    29                 }
    30                 
    31                 if (((m + n) & 0x1) == 0) {
    32                     if (aidx == m) {
    33                         ret2 = (double) nums2[bidx];
    34                     } else if (bidx == n) {
    35                         ret2 = (double) nums1[aidx];
    36                     } else {
    37                         ret2 = (double) Math.min(nums1[aidx], nums2[bidx]);
    38                     }
    39                 } else {
    40                     ret2 = ret1;
    41                 }
    42                 
    43                 break;
    44             }
    45         }
    46         
    47         return (ret1 + ret2) * 0.5;
    48     }
    49 }
  • 相关阅读:
    移动端,多屏幕尺寸高清屏retina屏适配的解决方案
    angular 关于 factory、service、provider的相关用法
    2016最新手机号码正则、身份证JS正则表达式
    凸包总结
    BZOJ 3653: 谈笑风生(DFS序+可持久化线段树)
    BZOJ 3652: 大新闻(数位DP+概率论)
    BZOJ 1062: [NOI2008]糖果雨(二维树状数组)
    纪中集训 Day 8 & Last Day
    纪中集训 Day 7
    纪中集训 Day 6
  • 原文地址:https://www.cnblogs.com/joycelee/p/5403913.html
Copyright © 2011-2022 走看看