• 0004. Median of Two Sorted Arrays (H)


    Median of Two Sorted Arrays (H)

    题目

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

    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
    

    题意

    给定两个升序数组,要求找到由这两个数组组成的数集合的中位数。时间复杂度要求为(O(log(m+n)))

    思路

    常规方法合并后取中位数,复杂度为(O(m+n))。(在合并中排到指定个数时即可停止并返回输出)

    复杂度为(O(log(m+n)))的方法:结合二分和递归,将问题转化为求两数组组成的集合中第k小的数。每次都比较数组A和B中第k/2小的数A[k/2-1]和B[k/2-1],这里会有以下三种情况:

    (记两数组合并后的升序数组为C)

    • A[k/2-1] < B[k/2-1],说明A[0]-A[k/2-1]这k/2个数均小于B[k/2-1],而B[k/2-1]前有k/2-1个数也小于它,那么即使A[k/2-1]取最大,也只能在C中排到第k-1位,不可能是第k小,所以将A[0]-A[k/2-1]这k/2个数全部删去,问题转化为在剩余数组成的集合中求第k-p小的数(用p表示是因为不一定每次都能删去k/2个数,A的长度可能小于k/2,这时会把整个数组删去)。
    • A[k/2-1] > B[k/2-1],与上面的情况相似,这时删去B中的k/2个数,在剩余数组成的集合中求第k-q小的数。
    • A[k/2-1] = B[k/2-1],这时A中有k/2-1个数比A[k/2-1]小,B中也有k/2-1个数比B[k/2-1]小,共有k-2个数比这两个值小,那么在C中A[k/2-1]和B[k/2-1]正好是第k-1和k小的数(并列),即所求的中位数就是A[k/2-1] (或B[k/2-1])。

    处理完递归,来考虑边界条件,共有三种情况:

    • 当一个数组中所有数都被排除后,只要在另一个数组中找到对应的第k小数即可。
    • 当k=1时,只要返回两个数组第一个元素中最小的那个。
    • A[k/2-1] = B[k/2-1],已包含在递归处理中。

    代码中为了方便处理,总是保持A为长度较小的数组。


    代码实现

    Java

    class Solution {
        public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
            int total = nums1.length + nums2.length;
            // 将奇偶两种情况统一处理
            int a = findkth(nums1, 0, nums1.length - 1, nums2, 0, nums2.length - 1, (total + 1) / 2);
            int b = findkth(nums1, 0, nums1.length - 1, nums2, 0, nums2.length - 1, (total + 2) / 2);
            return 1.0 * (a + b) / 2;
        }
        
        public static int findkth(int[] A, int as, int ae, int[] B, int bs, int be, int k) {
            int alen = ae - as + 1;
            int blen = be - bs + 1;
            // 边界条件处理
            if (alen > blen) {
                return findkth(B, bs, be, A, as, ae, k);
            } else if (alen == 0) {
                return B[k - 1];
            } else if (k == 1) {
                return Math.min(A[as], B[bs]);
            }
            // 递归处理
            int p = Math.min(alen, k / 2);
            int q = k - p;
            if (A[as + p - 1] < B[bs + q - 1]) {
                return findkth(A, as + p, ae, B, bs, be, k - p);
            } else if (A[as + p - 1] > B[bs + q - 1]) {
                return findkth(A, as, ae, B, bs + q, be, k - q);
            } else {
                return A[as + p - 1];
            }
        }
    }
    

    JavaScript

    /**
     * @param {number[]} nums1
     * @param {number[]} nums2
     * @return {number}
     */
    var findMedianSortedArrays = function (nums1, nums2) {
      let len = nums1.length + nums2.length
      let mid1 = findK(nums1, 0, nums1.length - 1, nums2, 0, nums2.length - 1, Math.floor((len + 1) / 2))
      let mid2 = findK(nums1, 0, nums1.length - 1, nums2, 0, nums2.length - 1, Math.floor((len + 2) / 2))
      return (mid1 + mid2) / 2
    }
    
    let findK = function (nums1, l1, r1, nums2, l2, r2, k) {
      if (r1 - l1 > r2 - l2) {
        return findK(nums2, l2, r2, nums1, l1, r1, k)
      }
      if (l1 > r1) {
        return nums2[k - 1]
      }
      if (k === 1) {
        return Math.min(nums1[l1], nums2[l2])
      }
    
      let p = Math.min(r1 - l1 + 1, Math.floor(k / 2))
      let q = k - p
    
      if (nums1[l1 + p - 1] < nums2[l2 + q - 1]) {
        return findK(nums1, l1 + p, r1, nums2, l2, r2, k - p)
      } else if (nums1[l1 + p - 1] > nums2[l2 + q - 1]) {
        return findK(nums1, l1, r1, nums2, l2 + q, r2, k - q)
      } else {
        return nums1[l1 + p - 1]
      }
    }
    
  • 相关阅读:
    一些基本数据类型问题
    File创建
    zip解压文件java
    Arrays 的copyOf()
    浏览器客户端-自定义服务端
    TCP并发复制上传文件
    TCP传输过程复制文件
    TCP通讯
    TCP通讯
    css3 animation
  • 原文地址:https://www.cnblogs.com/mapoos/p/13130249.html
Copyright © 2020-2023  润新知