自学内容网 自学内容网

学习记录:js算法(四十二): 寻找两个正序数组的中位数

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

给定两个大小分别为 mn 的正序(从小到大)数组 nums1nums2。请你找出并返回这两个正序数组的 中位数

示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2

示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

我的思路
排序,然后根据长度进行判断;想使用二分法,但是没找到二分法的判断条件,卡壳了。
网上思路
二分法

我的思路

var findMedianSortedArrays = function (nums1, nums2) {
    let arr = [...nums1, ...nums2].sort((a, b) => a - b)
    let len = arr.length
    return len % 2 === 0 ? (arr[len / 2] + arr[len / 2 - 1]) / 2 : arr[(len - 1) / 2]
};

讲解

  1. 合并数组并排序
  2. 取余判断
    • 如果无余数,那么下标就是 arr.length / 2arr.length / 2 - 1
    • 有余数,那么下标就是 (arr.length - 1) / 2

网上思路

/**
 * 二分解法
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number}
 */
var findMedianSortedArrays = function(nums1, nums2) {
  // make sure to do binary search for shorten array
  if (nums1.length > nums2.length) {
    [nums1, nums2] = [nums2, nums1]
  }
  const m = nums1.length
  const n = nums2.length
  let low = 0
  let high = m
  while(low <= high) {
    const i = low + Math.floor((high - low) / 2)
    const j = Math.floor((m + n + 1) / 2) - i

    const maxLeftA = i === 0 ? -Infinity : nums1[i-1]
    const minRightA = i === m ? Infinity : nums1[i]
    const maxLeftB = j === 0 ? -Infinity : nums2[j-1]
    const minRightB = j === n ? Infinity : nums2[j]

    if (maxLeftA <= minRightB && minRightA >= maxLeftB) {
      return (m + n) % 2 === 1
        ? Math.max(maxLeftA, maxLeftB)
        : (Math.max(maxLeftA, maxLeftB) + Math.min(minRightA, minRightB)) / 2
    } else if (maxLeftA > minRightB) {
      high = i - 1
    } else {
      low = low + 1
    }
  }
};

讲解
由于题中给出的数组都是排好序的,在排好序的数组中查找很容易想到可以用二分查找, 这里对数组长度小的做二分,
保证数组A数组Bpartition 之后
len(Aleft)+len(Bleft)=(m+n+1)/2 - m数组A 的长度, n数组B 的长度
数组A 的做 partition 的位置是区间 [0,m]
如图:
在这里插入图片描述

下图给出几种不同情况的例子(注意但左边或者右边没有元素的时候,左边用INF_MIN,右边用INF_MAX表示左右的元素:
在这里插入图片描述
下图给出具体做的partition 解题的例子步骤,
在这里插入图片描述
关键点分析
暴力求解,在线性时间内 merge 两个排好序的数组成一个数组。
二分查找,关键点在于
partition 两个排好序的数组成左右两等份,partition 需要满足 len(Aleft)+len(Bleft)=(m+n+1)/2 - m数组A 的长度, n数组B 的长度
并且 partitionA 左边最大 (maxLeftA), A 右边最小 (minRightA) , B 左边最大 (maxLeftB) , B 右边最小 (minRightB) 满足
(maxLeftA <= minRightB && maxLeftB <= minRightA)
有了这两个条件,那么 median 就在这四个数中,根据奇数或者是偶数,

// 奇数:
median = max(maxLeftA, maxLeftB)
// 偶数:
median = (max(maxLeftA, maxLeftB) + min(minRightA, minRightB)) / 2

作者:lucifer
链接:点击跳转

总结

这位大佬的笔记很详细,真的很实用!


原文地址:https://blog.csdn.net/weixin_48677331/article/details/142442115

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!