• 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
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  • 相关阅读:
    bzoj2064分裂(dp)
    关于逆元的学习笔记(尚未完成)
    线性基学习笔记
    bzoj2460元素(线性基,贪心)
    CF280C Game on tree(期望dp)
    XJOI contest800
    关闭极域电子教室学生端的各种方法
    大坑!有网,电脑qq登不上去!!
    4.25 ZJOI2017 10AM
    bzoj1621
  • 原文地址:https://www.cnblogs.com/MarcLiu/p/14235827.html
Copyright © 2020-2023  润新知