leetcode 4. Median of Two Sorted Arrays

原创 2016年08月31日 16:29:52
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

两个方法找到两个排序数组的中位数,方法一思路是把两个数组合并成一个数组,然后求中值。这里需要注意的就是当数组个数为偶数时,要除以2.0,最后才能得到double值,否则只能得到整数部分。花费时长6ms。

public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        int[] nums3 = new int[m + n];
        int i = 0;
        int j = 0;
        int k = 0;
        while(i < m && j < n){
            if(nums1[i] < nums2[j]){
                nums3[k] = nums1[i];
                i++;
            }else if(nums1[i] > nums2[j]){
                nums3[k] = nums2[j];
                j++;
            }else{
                nums3[k] = nums1[i];
                nums3[++k] = nums2[j];
                i++;
                j++;
            }
            k++;
        }
        if(i == m){
            for(int t = j; j < n; j++){
                nums3[k] = nums2[j];
                k++;
            }
        }
        if(j == n){
            for(int t = i; i < m; i++){
                nums3[k] = nums1[i];
                k++;
            }
        }
        if(k % 2 == 0){
            return (nums3[k/2] + nums3[k/2-1]) / 2.0;
        }else{
            return nums3[(k-1)/2];
        }
    }
}

方法二,在discuss中看到一种更为普通的解法,且效率更好。4ms。以下为我的翻译~

首先我们需要明白中位数的作用是什么,它将一个集合分成长度相等的两部分,一边比另一边大。

我们在位置i将A数组分成两部分,A的元素个数为m,共有i=(0~m) m+1个划分位置,len(left_A)=i,len(right_A)=m-i,当i=0时,left_A是空的,当i=m时right_A是空的。


同理,在j位置将B数组划分,B的元素个数是n。


将left_A和left_B放到一组,right_A和right_B放到一组,命名为left_part和right_part。前提是保证m <= n 否则在运行过程中,数组下标会越界。


如果我们能确保


那么就可以得到中位数 median = (max(left_part) + min(right_part))/2.

为了保证上述两个条件,我们只需保证


(假设对所有的A[i-1],B[j-1],A[i],B[j]都是合法的,i=0 或 m, j=0 或 n的情况再单独讨论)

所以我们需要做的就是在i=(0~m)中,找到一个合适的i,使得B[j-1] <= A[i] and A[i-1] <= B[j] (j = (m+n+1)/2-i)。

算法如下:

  1. 使imin = 0, imax = m,在[imin, imax]中找合适的i;
  2. 使i = (imin + imax) / 2,j = (m + n + 1) / 2 - i;
  3. 现在已经保证了len(left_part) == len(right_part),接下来只有3中情况需要讨论:
<a> B[j-1] <= A[i] and A[i-1] <= B[j],意味着找到合适的i,可以停止搜索。
<b> B[j-1] > A[i],意味着找到的i偏小,需要增加i的值,使得A[i]变大,同时B[j-1]变小。set imin = i + 1,调整搜索范围为[i+1,imax]
回到第2步。
<c> A[i-1] > B[j],意味着找到的i偏大,需要减小i的值,set imax = i - 1,然后回到第2步。
找到合适的i以后,
median = max(A[i-1], B[j-1]) (当m + n 是奇数时)
median = (max(A[i-1], B[j-1]) + min(A[i], B[j])) / 2.0 (当m + n 是偶数时)
接下来讨论边界情况,当i=0,m j=0,n 时,A[i-1],A[i],B[j-1],B[j]都是不存在。
整个过程中,我们需要做的是保证 max(left_part) <= min(right_part)。当上述4个值都存在时,我们需要检查 B[j-1] <= A[i] and A[i-1] <= B[j],
而比如当i=0时,A[i-1]不存在,因此我们不需要检查A[i-1] <= B[j]这个条件。
所以总共有一下三种情况:

public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        if(m > n){ // 保证m <= n的
            int[] temp = nums1;
            nums1 = nums2;
            nums2 = temp;
            int t = m;
            m = n;
            n = t;
        }
        int imin = 0;
        int imax = m;
        int i, j, max_of_left, min_of_right;
        double mid=0;
        while(imin <= imax){
            i = (imin + imax) / 2;
            j = (m + n + 1) / 2 - i;
            if(j > 0 && i < m && nums2[j - 1] > nums1[i]){ // 当i偏小时
                imin = i + 1;
            }else if(i > 0 && j < n && nums1[i - 1] > nums2[j]){ // 当i偏大时
                imax = i - 1;
            }else{<span style="white-space:pre">	</span>// i在合适位置
                if(i == 0){
                    max_of_left = nums2[j - 1];
                }else if(j == 0){
                    max_of_left = nums1[i - 1];
                }else{
                    max_of_left = Math.max(nums1[i - 1], nums2[j - 1]);
                }
                if((m + n) % 2 ==1){
                    mid = max_of_left;
                    break;
                }
                if(i == m){
                    min_of_right = nums2[j];
                }else if(j == n){
                    min_of_right = nums1[i];
                }else{
                    min_of_right = Math.min(nums1[i], nums2[j]);
                }
                mid = (max_of_left + min_of_right) / 2.0;
                break;
            }
        }
        return mid;
    }
}




相关文章推荐

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
  • 1054

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
  • 128

[编程练习][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
  • 190

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个字)