zoukankan      html  css  js  c++  java
  • LeetCode 4. Median of Two Sorted Arrays

    原题链接在这里:https://leetcode.com/problems/median-of-two-sorted-arrays/

    题目:

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

    You may assume nums1 and nums2 cannot be 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

    题解:

    首先我们先明确什么是median,即中位数.

    引用Wikipedia对中位数的定义:

    计算有限个数的数据的中位数的方法是:把所有的同类数据按照大小的顺序排列。如果数据的个数是奇数,则中间那个数据就是这群数据的中位数;如果数据的个数是偶数,则中间那2个数据的算术平均值就是这群数据的中位数。

    所以要看 m+n是技术还是偶数,若是偶数,应该返回中间两个数的算术平方和。

    在比较过程中,取nums1得中位数,nums2的中位数比较,若是nums1的中位数小,说明要找的中位数肯定不包括在 nums1的中位数和nums1中位数前面的数,为什么呢?如下是说明例子:

     将本体求中位数的要求调整为将两个数组整体合并排序后求其第k个数。下面用一个例子来说明:
    图一、例子示意图
          A班和B班的同学人数分别为aEnd与bEnd,有天体育老师说要找他们中间第k矮的同学,于是先将两班的同学按从小到大的顺序站成两队。假设k是为13。那此时A班派出第x矮的同学,B班派出第y矮的同学来比较(注意:此时x+y<=k)。
          若x为6,y为7。如果A的第6位同学比B的第7位同学还要矮,那如果两班整体排序,那A班的6位同学一定是要站在B班的第7位前面,最多A班第6位就站在B班第7位的前一位,最多就整体排第12,怎么都轮不到他排第k=13个。于是可以把A班前6位丢掉,在剩下的两个队列里面找。但是就不再是找第k个,而是找第k-x个了。因为x做了基数被丢掉了。
     
    进入findKth后,为了方便比较若是前一个段长度 大于 后一段,就调换过来。当前面一个缩小到0时,就是取后面一个第k个即可。
    前面取Math.min(k/2,m), k/2时因为k是int, 结果永远是向下取整,和m取小是因为 k/2大于前一段的长度时只保存m即可。当前一段取空了,后面一段多取一些。
    递归过程中,会更改前一段长度,后一段长度和k, 所以终止条件有两个:一个是当较小一段长度 == 0时,取另一段的中点即可。另一个是当段缩减到1时,也就是 k == 1时,此时取两个元素中较小值就可以了。
    比较时,若nums1中位数大,去掉nums1 前一段,并且在剩下部分中取第k-pa小值. 反之 nums2中位数大是做相对应的操作即可。多是两个数相同,那么就返回其中一个即可。
    Time Complexity: O(log n) n = nums1.length+num2.length. 最坏的情况每次去掉一半,一直走到k=1.
    Space: O(log n), 用了logn 层stack.

    AC Java:

     1 public class Solution {
     2     public double findMedianSortedArrays(int[] nums1, int[] nums2) {
     3         int m = nums1.length;
     4         int n = nums2.length;
     5         int sum = m+n;
     6         if(sum % 2 != 0){
     7             return findKth(nums1, 0, m - 1, nums2, 0, n - 1, sum / 2 + 1);
     8         }else{
     9             return (findKth(nums1, 0, m - 1, nums2, 0, n - 1, sum / 2) + findKth(nums1, 0, m - 1, nums2, 0, n - 1, sum / 2 + 1)) / 2.0;
    10         }
    11     }
    12     private double findKth(int[] a, int aStart, int aEnd, int[] b, int bStart, int bEnd, int k){
    13         int m = aEnd - aStart + 1;
    14         int n = bEnd - bStart + 1;
    15         //统一长度,将短的array放到前面来
    16         if(m > n){
    17             return findKth(b,bStart,bEnd,a,aStart,aEnd,k);
    18         }
    19         
    20         //a is an empty array
    21         if(m == 0){
    22             return b[bStart + k -1];
    23         }
    24         
    25         //Stop condition, 都减到头了, 都剩下了一个元素
    26         if(k == 1){
    27             return Math.min(a[aStart], b[bStart]);
    28         }
    29         
    30         int pa = Math.min(k / 2,m);
    31         int pb = k - pa;
    32         
    33         if(a[aStart + pa -1] < b[bStart + pb - 1]){
    34             return findKth(a, aStart + pa, aEnd, b, bStart, bEnd, k - pa);
    35         }else if(a[aStart + pa -1] > b[bStart + pb - 1]){
    36             return findKth(a, aStart, aEnd, b, bStart + pb, bEnd, k - pb);
    37         }else{
    38             return a[aStart + pa -1];
    39         }
    40     }
    41 }

    参见这两篇帖子:http://www.cnblogs.com/springfor/p/3861890.html

    http://blog.csdn.net/yutianzuijin/article/details/11499917

  • 相关阅读:
    算法训练 P1103
    算法训练 表达式计算
    算法训练 表达式计算
    基础练习 时间转换
    基础练习 字符串对比
    Codeforces 527D Clique Problem
    Codeforces 527C Glass Carving
    Codeforces 527B Error Correct System
    Codeforces 527A Glass Carving
    Topcoder SRM 655 DIV1 250 CountryGroupHard
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/4886836.html
Copyright © 2011-2022 走看看