Algorithm problem - look for a median of two ordered arrays

Title Description

Given two ordered arrays of size and nums1 m and n nums2.

Please find both the median and orderly array, and requires time complexity of the algorithm is O (log (m + n)).

You can not assume nums1 and nums2 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

Source: stay button (LeetCode)

Links: https://leetcode-cn.com/problems/median-of-two-sorted-arrays

answer

My Solution:

My idea: after the merger of the two array sort, and then find the median.

private static double findMedianSortedArrays(int[] nums1, int[] nums2) {
    if (nums1.length==0&&nums2.length==0){
        return 0;
    }
    double media = 0;
    int[] both = new int[nums1.length+nums2.length];
    System.arraycopy(nums1,0,both,0,nums1.length);
    System.arraycopy(nums2,0,both,nums1.length,nums2.length);
    Arrays.sort(both);
    if (both.length%2==0){
        media=(both[both.length/2-1]+both[both.length/2])/2.0;
    } else {
        media=both[both.length/2];
    }
    return media;
}

As used herein, the API java provides simplified operation of merging and sorting the array, a bit tricky, but in fact does not meet the requirements of the subject, the subject requires time complexity is O (log (m + n)), so that others look how to do it

Official Solution:

Ideas:

To solve this problem, we need to understand "what is the role of the median." In statistics, the median is used to:

One set into two subsets of equal length, wherein a subset of the elements are always larger than the other elements in the subset.

If you understand the role of division of the median, we would be very close to the answer.

First, let us at any position i of A is divided into two parts:

      left_A             |        right_A
A[0], A[1], ..., A[i-1]  |  A[i], A[i+1], ..., A[m-1]

Since there are m elements A, so we have m + 1 division method (i = 0~m).

we know:

len(left_A)=i,len(right_A)=m−i.

NOTE: When i = 0, left_A empty set, and when i = m, right_A empty set.

In the same way, we will be at any position j B is divided into two parts:

      left_B             |        right_B
B[0], B[1], ..., B[j-1]  |  B[j], B[j+1], ..., B[n-1]

The left_A left_B and into a collection, and placed into another set right_A and right_B. Then these two new collection named 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 confirm:

len(left_part)=len(right_part)

max(left_part)≤min(right_part)

So, we have all the elements {A, B} is divided into two parts of equal length, and where the element portion is always larger than the other part of the element. Then:

median= [max(left_part)+min(right_part)]/2

To ensure these two conditions, we only need to ensure that:

ps.1 To simplify the analysis, assume I A [i-1], B [j-1], A [i], B [j] is always present, even if it appears i = 0, i = m, j = 0, or j = n such critical conditions.
I will discuss how to deal with these critical values at the end.

ps.2 Why n≥m? Since 0≤i≤m and j = (m + n + 1) / 2-i, I j must ensure not negative. If n <m, then j will be negative, and this will cause the wrong answer.

So, we need to do is:

Search and find the target object i in [0, m] in that:

B [j-1] ≤A [i] 且 A [i-1] ≤B [j], 其中 j = (m + n + 1) / 2-i

Then, we can be a binary tree search, follow these steps:

1. setting imin = 0, imax = m, and then to start the search [imin, imax] in.

2. Order i = (imin + imax) / 2, j = (m + n + 1) / 2-i

3. Now we have len (left_part) = len (right_part). And we will only meet three conditions:

B [j-1] ≤A [ i] and A [i-1] ≤B [ j]:
This means that we find the target object i, so you can stop searching.

B [j-1]> A [i]:
This means that A [i] is too small, so we have to adjust i B [j-1] ≤A [ i].

We can increase i do?

It is because when the time is increased i, j will be reduced.
Thus B [j-1] may be reduced, and A [i] increases, then B [j-1] ≤A [ i] can be satisfied.

We can reduce i do?

No, because when i is reduced, j will be increased.
Thus B [j-1] is increased, and A [i] decreases, then B [j-1] ≤A [ i] may not satisfy.
So we must increase i. In other words, we have to adjust your search [i + 1, imax].
Thus, setting imin = i + 1, and go to step 2.

A [i-1]> B [j]:
This means that A [i-1] is too large, so that we must reduce the i A [i-1] ≤B [ j].
In other words, we have to adjust your search [imin, i-1].
Thus, setting imax = i-1, and go to step 2.

When finding the target object i, median: max (A [i-1], B [j-1]), when m + n is an odd number

[max (A [-I. 1], B [-J. 1]) + min (A [I], B [J])] / 2 , when m + n is an even number when

Now, let us consider the threshold values i = 0, i = m, j = 0, j = n, At this time, A [i-1], B [j-1], A [i], B [j] It may not exist.
In fact, this case is much easier than you think.

We need to do is make sure max (left_part) ≤min (right_part) . So, if i and j is not a critical value (which means that A [i-1], B [j-1], A [i], B [j] all exist), then we must also check the B [j-1 ] ≤A [i] and A [i-1] ≤B [ j] holds.
However, if] A [i-1], B [j-1], A [i], B [j] is not present in the section, then we need to check only one of these two conditions (or no check).
For example, if i = 0, then A [i-1] does not exist, we would not need to check A [i-1] ≤B [ j] holds.
So, we need to do is:

Search and find the target object i in [0, m] in that:

(j=0 or i = m or B[j−1]≤A[i]) 或是
i=0 or j = n or A[i−1]≤B[j]), 其中 j = (m+n+1)/2−i

In cycle search, we will only meet three conditions:

j = 0 or i = m or B [j-1] ≤A [i]) or i = 0 or j = n or A [i-1] ≤B [j]), which means i is perfect we can stop searching.
j> 0 and i <m and B [j-1]> A [i] which means i too small, we have to increase it.
i> 0 and j <n and A [i-1]> B [j] This means ii too, it must be reduced.
i <m⟹j> 0 and i> 0⟹j <n always true, because:

Therefore, in the case of 2 and 3, we need to check for j> 0 or j <n holds.

public double findMedianSortedArrays(int[] A, int[] B) {
    int m = A.length;
    int n = B.length;
    if (m > n) { // to ensure m<=n
        int[] temp = A; A = B; B = temp;
        int tmp = m; m = n; n = tmp;
    }
    int iMin = 0, iMax = m, halfLen = (m + n + 1) / 2;
    while (iMin <= iMax) {
        int i = (iMin + iMax) / 2;
        int j = halfLen - i;
        if (i < iMax && B[j-1] > A[i]){
            iMin = i + 1; // i is too small
        }
        else if (i > iMin && A[i-1] > B[j]) {
            iMax = i - 1; // i is too big
        }
        else { // i is perfect
            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 (i == m) { minRight = B[j]; }
            else if (j == n) { minRight = A[i]; }
            else { minRight = Math.min(B[j], A[i]); }

            return (maxLeft + minRight) / 2.0;
        }
    }
    return 0.0;
}

More difficult to understand that problem solutions visit:? Https://leetcode-cn.com/problems/median-of-two-sorted-arrays

Guess you like

Origin www.cnblogs.com/hao-yu/p/11647855.html