LeetCode 热题 HOT 100 4. 寻找两个正序数组的中位数

174 阅读1分钟

题目

题解

暴力法

此方法就是简单暴力,直接合并排序后,通过数学公示推倒,时间复杂度还是挺好的。


/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number}
 */
var findMedianSortedArrays = function(nums1, nums2) {
    const sumLen = nums1.length + nums2.length
    const sortArr = [].concat(nums1, nums2).sort((a, b) => a - b) // 快排
    const mid = Math.floor(sumLen / 2)
    if (sumLen % 2 === 0) {
        return (sortArr[mid-1] + sortArr[mid])/2
    } else {
        return sortArr[mid]
    }
};

// 时间复杂度 O((m+n)log(m+n))
// 空间复杂度 O(m+n)

归并排序

关于归并排序不熟悉的可以看我的这篇文章快速入门归并排序。这里就不画图了。


/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number}
 */
var findMedianSortedArrays = function(nums1, nums2) {
    // 通过归并排序合并数组,再取中位
    const n1Len = nums1.length
    const n2Len = nums2.length
    const sortArr = []
    while(nums1.length && nums2.length) {
        if (nums1[0] < nums2[0]) {
            sortArr.push(nums1.shift())
        } else {
            sortArr.push(nums2.shift())
        }
    }
    while(nums1.length) {
        sortArr.push(nums1.shift())
    }
    while(nums2.length) {
        sortArr.push(nums2.shift())
    }
    const mid = Math.floor(sortArr.length / 2)
    if (sortArr.length % 2 === 0) {
        return (sortArr[mid-1] + sortArr[mid]) / 2
    } else {
        return sortArr[mid]
    }
};

// 空间复杂度 O(m+n)
// 时间复杂度 O(m+n)

二分查找


/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number}
 */
var findMedianSortedArrays = function(nums1, nums2) {
   let len1 = nums1.length;
   let len2 = nums2.length;
   // 对长度短的数组进行二分查找    
   if (len1 > len2) {
       return findMedianSortedArrays(nums2, nums1);
   }
   let len = len1 + len2;
   let start = 0;
   let end = len1;
   // 两个数组左分段的长度    
   let partLen1 = 0;
   let partLen2 = 0;

   while (start <= end) {
       partLen1 = (start + end) >> 1;
       partLen2 = ((len + 1) >> 1) - partLen1;

       let l1 = partLen1 === 0? -Infinity : nums1[partLen1 - 1];
       let l2 = partLen2 === 0? -Infinity : nums2[partLen2 - 1];
       let r1 = partLen1 === len1 ? Infinity : nums1[partLen1];
       let r2 = partLen2 === len2 ? Infinity : nums2[partLen2];

       if (l1 > r2) {
            end = partLen1 - 1;
       } else if (l2 > r1) {
            start = partLen1 + 1;
       } else { // 满足条件的情况: l1 <= r2 && l2 <= r1
            return len % 2 === 0 ?
            (Math.max(l1, l2) + Math.min(r1, r2) ) / 2 : 
            Math.max(l1, l2)
       }
   }
};


未完成

  • 二分查找的图解补充
  • 双指针的实现方式

ps: 欢迎关注我的公众号 xyz编程日记,觉得不错的帮忙点个👍,点个在看。