zoukankan      html  css  js  c++  java
  • LeetCode每日一刷-寻找两个正序数组的中位数

    4. 寻找两个正序数组的中位数

    给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。

    进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决此问题吗?

    首先,中位数是按顺序排列的一组数据中居于中间位置的数,如果观察值有偶数个,通常取最中间的两个数值的平均数作为中位数。

    最直观的方法就是排序和双指针。

    • 使用归并的方式,合并两个有序数组,得到一个大的有序数组。大的有序数组的中间位置的元素,即为中位数。
    • 不需要合并两个有序数组,只要找到中位数的位置即可。由于两个数组的长度已知,因此中位数对应的两个数组的下标之和也是已知的。维护两个指针,初始时分别指向两个数组的下标 00 的位置,每次将指向较小值的指针后移一位(如果一个指针已经到达数组末尾,则只需要移动另一个数组的指针),直到到达中位数的位置。

    其中归并排序算法忽略,给出双指针算法,能通过LeetCode测试,时间复杂度O(m+n)。

    首先是怎么将奇数和偶数的情况合并一下。

    用 len 表示合并后数组的长度,如果是奇数,我们需要知道第 (len+1)/2 个数就可以了,如果遍历的话需要遍历 int(len/2 ) + 1 次。如果是偶数,我们需要知道第 len/2和 len/2+1 个数,也是需要遍历 len/2+1 次。所以遍历的话,奇数和偶数都是 len/2+1 次。

    返回中位数的话,奇数需要最后一次遍历的结果就可以了,偶数需要最后一次和上一次遍历的结果。所以我们用两个变量 left 和 right,right 保存当前循环的结果,在每次循环前将 right 的值赋给 left。这样在最后一次循环的时候,left 将得到 right 的值,也就是上一次循环的结果,接下来 right 更新为最后一次的结果。

    循环中该怎么写,什么时候 A 数组后移,什么时候 B 数组后移。用 aStart 和 bStart 分别表示当前指向 A 数组和 B 数组的位置。如果 aStart 还没有到最后并且此时 A 位置的数字小于 B 位置的数组,那么就可以后移了。也就是aStart<m&&A[aStart]< B[bStart]。

    但如果 B 数组此刻已经没有数字了,继续取数字 B[ bStart ],则会越界,所以判断下 bStart 是否大于数组长度了,这样 || 后边的就不会执行了,也就不会导致错误了,所以增加为 aStart<m&&(bStart) >= n||A[aStart]<B[bStart]) 。

     1 public double FindMedianSortedArrays(int[] A, int[] B)
     2         {
     3             int m = A.Length;
     4             int n = B.Length;
     5             int len = m + n;
     6             int aStart = 0, bStart = 0;
     7             int left = 0, right = 0;
     8             for (int i = 0; i <= len/2; i++)
     9             {
    10                 left = right;
    11                 if (aStart < m && (bStart >= n || A[aStart] < B[bStart]))
    12                 {
    13                     right = A[aStart];
    14                     aStart++;
    15                 }
    16                 else
    17                 {
    18                     right = B[bStart];
    19                     bStart++;
    20                 }
    21             }
    22             if ((m + n) % 2 == 0)
    23             {
    24                 return (left + right) / 2.0;
    25             }
    26             else
    27             {
    28                 return right;
    29             }
    30         }

    但是要达到最优解O(log(m+n)),看到log,明显需要用到二分的方法。(未完待续)

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  • 相关阅读:
    android29
    android28
    android27
    android26
    Dynamics CRM2011 MspInstallAction failed when installing an Update Rollup
    Dynamics CRM Import Solution Attribute Display Name description is null or empty
    The service cannot be activated because it does not support ASP.NET compatibility
    IIS部署WCF报 无法读取配置节“protocolMapping”,因为它缺少节声明
    Unable to access the IIS metabase.You do not have sufficient privilege
    LM算法与非线性最小二乘问题
  • 原文地址:https://www.cnblogs.com/MarcLiu/p/14235827.html
Copyright © 2011-2022 走看看