LeetCode 4 - Median of Two Sorted Arrays

原创 2015年07月08日 11:23:10

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


My O(m+n) Code

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int totalSize = nums1.size()+nums2.size();
        vector<int> nums;

        int minNumber;
        int i = 0, j = 0;
        while (i < nums1.size() && j < nums2.size())
        {
            minNumber = min(nums1[i], nums2[j]);
            //cout << "i: " << i << " j: " << j << endl;
            //cout << "minNumber: " << minNumber << endl;
            for (; i < nums1.size(); i++)
            {
                if (nums1[i] == minNumber)
                {
                    //cout << "nums1[" << i << "]: " << nums1[i] << endl;
                    nums.push_back(nums1[i]);
                }
                else
                {
                    break;
                }
            }

            for (; j < nums2.size(); j++)
            {
                if (nums2[j] == minNumber)
                {
                    //cout << "nums2[" << j << "]: " << nums2[j] << endl;
                    nums.push_back(nums2[j]);
                }
                else
                {
                    break;
                }
            }
        }

        if (i < nums1.size())
            for (; i < nums1.size(); i++)
                    nums.push_back(nums1[i]);

        if (j < nums2.size())
            for (; j < nums2.size(); j++)
                    nums.push_back(nums2[j]);

        /*
        cout << "nums: ";
        for (int k = 0; k < totalSize; k++)
            cout << nums[k] << " ";
        cout << endl;
        */

        double median;
        if (totalSize % 2 == 1)
            median = nums[(totalSize-1)/2];
        else
            median = 0.5 * (nums[(totalSize-1)/2] + nums[(totalSize-1)/2 + 1]);

        return median;
    }
};
Runtime: 48 ms

My O(log(min(m,n))) Code

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size();
        int n = nums2.size();
        if (m > n)
            return findMedianSortedArrays(nums2, nums1);

        int start = 0, end = m;
        int i, j;
        while (start <= end)
        {
            i = (start+end)/2;
            j = (m+n+1)/2 - i;
            cout << "start: " << start << " end: " << end
                 << " i: " << i << " j: " << j << endl;

            if (i == 0 || j == n || nums1[i - 1] <= nums2[j])
                if (j == 0 || i == m || nums1[i] >= nums2[j-1])
                    break;
                else
                    start = i + 1;
            else
                end = i - 1;
        };

        int maxNum;
        if (i == 0)
            maxNum = nums2[j-1];
        else if (j == 0)
            maxNum = nums1[i-1];
        else
            maxNum = max(nums1[i-1], nums2[j-1]);

        int minNum;
        if (i == m)
            minNum = nums2[j];
        else if (j == n)
            minNum = nums1[i];
        else
            minNum = min(nums1[i], nums2[j]);

        double median;
        if (i+j == (m-i)+(n-j))
            median = 0.5*(minNum+maxNum);
        else
            median = maxNum;

        return median;
    }
};
Runtime: 44 ms

Explanation of O(log(min(m, n))) Code

Given a sorted array A with length m, we can split it into two part:

{ A[0], A[1], ... , A[i - 1] } | { A[i], A[i + 1], ... , A[m - 1] }

All elements in right part are greater than elements in left part.

The left part has "i" elements, and right part has "m - i" elements.

There are "m + 1" kinds of splits. (i = 0 ~ m)

When i = 0, the left part has "0" elements, right part has "m" elements.

When i = m, the left part has "m" elements, right part has "0" elements.

For array B, we can split it with the same way:

{ B[0], B[1], ... , B[j - 1] } | { B[j], B[j + 1], ... , B[n - 1] }

The left part has "j" elements, and right part has "n - j" elements.

Put A's left part and B's left part into one set. (Let's name this set "LeftPart")

Put A's right part and B's right part into one set. (Let's name this set"RightPart")

            LeftPart           |            RightPart 
{ 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) LeftPart's length == RightPart's length (or RightPart's length + 1)

 2) All elements in RightPart are greater than elements in LeftPart.

Then we split all elements in {A, B} into two parts with eqaul length, and one part is

always greater than the other part. Then the median can be easily found.

To ensure these two condition, 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]

     considering edge values, we need to ensure:

           (j == 0 or i == m or B[j - 1] <= A[i]) and 

               (i == 0 or j == n or A[i - 1] <= B[j])

So, all we need to do is:

 Search i from 0 to m, to find an object "i" to meet condition (1) and (2) above.

And we can do this search by binary search. How?

If B[j0 - 1] > A[i0], then the object "ix" can't be in [0, i0]. Why?

 Because if ix < i0, then jx = (m + n + 1) / 2 - ix > j0, 

 then B[jx - 1] >= B[j0 - 1] > A[i0] >= A[ix]. This violates

 the condition (2). So ix can't be less than i0.

And if A[i0 - 1] > B[j0], then the object "ix" can't be in [i0, m].

So we can do the binary search following steps described below:

1. set imin, imax = 0, m, then start searching in [imin, imax]

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

3. if B[j - 1] > A[i]: continue searching in [i + 1, imax]
   elif A[i - 1] > B[j]: continue searching in [imin, i - 1]
   else: bingo! this is our object "i"

When the object i is found, the median is:

max(A[i - 1], B[j - 1]) (when m + n is odd)

or (max(A[i - 1], B[j - 1]) + min(A[i], B[j])) / 2 (when m + n is even)

相关文章推荐

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 t...
  • fly_yr
  • fly_yr
  • 2015年08月22日 20:35
  • 1057

Leetcode刷题记—— 4. Median of Two Sorted Arrays(两有序数组的中位数)

一、题目叙述: There are two sorted arrays nums1 and nums2 of size m...

LeetCode (4)Median of Two Sorted Arrays

(4)Median of Two Sorted Arrays题目:两个已经排好序的数组nums1和nums2,大小分别为m和n,求两个已排数组中位数。总运行时间复杂度应该是O(log(m+n))。用例...

[LeetCode][4]Median of Two Sorted Arrays解析 -Java实现

Q: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the...

LeetCode 题目 4. Median of Two Sorted Arrays

题目原址 :点击打开链接   题目描述: There are two sorted arrays nums1 and nums2 of size m and n respectively...

leetcode #4: Median of Two Sorted Arrays

题目链接: Median of Two Sorted Arrays 这道题坑还是有点多的,刚看到的时候第一反应是:这不就是归并排序....还是图样啊。所以先这样提交了: class Sol...
  • wyxpku
  • wyxpku
  • 2016年07月31日 00:33
  • 130

[编程练习][Median of Two Sorted Arrays]<LeetCode-4>

题目来自leetcode https://oj.leetcode.com/problems/median-of-two-sorted-arrays/ There are two sorted ar...
  • drowzju
  • drowzju
  • 2014年12月04日 20:45
  • 192

Leetcode problem 4:Median of Two Sorted Arrays

DescriptionThere are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median...

LeetCode 4. Median of Two Sorted Arrays(两个有序数组的中位数)

原题网址:https://leetcode.com/problems/median-of-two-sorted-arrays/ There are two sorted arrays nums1 an...
  • jmspan
  • jmspan
  • 2016年05月01日 15:39
  • 529

Leetcode NO.4 Median of Two Sorted Arrays

本题题目要求如下: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the medi...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:LeetCode 4 - Median of Two Sorted Arrays
举报原因:
原因补充:

(最多只允许输入30个字)