• 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

  • 相关阅读:
    python学习之函数的参数
    python学习之文件修改及函数基础作业
    日志模块与 re 模块
    day23
    常用模块(二)
    day 22
    python 常用模块
    软件开发目录规范
    day 20
    python 的模块与包
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/4886836.html
Copyright © 2020-2023  润新知