返回

剖析JavaScript版 LeetCode.正序数组的中位数:二分查找的精髓

前端

从题目出发,理解何为中位数

在正式探究算法之前,我们先来明确什么是中位数。中位数,顾名思义,就是指一组数据中位于中间位置的那个值。在统计学中,中位数是用来衡量数据集中心位置的一个重要指标。

那么,如何寻找中位数呢?通常有两种常用的方法:

  • 直接排序法: 将数据从大到小或从小到大排序,然后取最中间位置的值作为中位数。
  • 二分查找法: 利用数据的有序性,通过不断地将数据一分为二,逐步逼近中位数。

深入二分查找,领略算法之美

在「正序数组的中位数」问题中,由于数据已经是有序的,因此采用二分查找法无疑是最佳的选择。二分查找的原理很简单:每次将数据一分为二,然后根据目标值所在的位置决定是继续在左半部分还是右半部分进行查找。如此反复,直至找到目标值或达到终止条件。

在JavaScript中,我们可以使用以下代码实现二分查找算法:

function binarySearch(arr, target) {
  let left = 0;
  let right = arr.length - 1;

  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    if (arr[mid] === target) {
      return mid;
    } else if (arr[mid] < target) {
      left = mid + 1;
    } else {
      right = mid - 1;
    }
  }

  return -1; // 未找到
}

融合二分与模拟,直面LeetCode挑战

有了二分查找的基础,我们就可以着手解决LeetCode上的「正序数组的中位数」问题了。具体思路如下:

  1. 将两个正序数组合并为一个新的数组,这样就可以利用二分查找法来找到中位数。
  2. 使用二分查找法在合并后的数组中找到中位数。
  3. 根据中位数的位置,判断中位数是来自第一个数组还是第二个数组。
/**
 * 给定两个正序数组,返回这两个数组的合并后的中位数。
 *
 * 示例 1:
 * 输入:nums1 = [1, 3], nums2 = [2]
 * 输出:2.00000
 *
 * 示例 2:
 * 输入:nums1 = [1, 2], nums2 = [3, 4]
 * 输出:2.50000
 *
 * 思路:
 * 1. 将两个正序数组合并为一个新的数组,这样就可以利用二分查找法来找到中位数。
 * 2. 使用二分查找法在合并后的数组中找到中位数。
 * 3. 根据中位数的位置,判断中位数是来自第一个数组还是第二个数组。
 */
const findMedianSortedArrays = (nums1, nums2) => {
  // 合并两个数组
  const mergedNums = nums1.concat(nums2);

  // 对合并后的数组进行排序
  mergedNums.sort((a, b) => a - b);

  // 计算合并后数组的长度
  const n = mergedNums.length;

  // 如果数组长度为奇数,则中位数就是中间位置的那个数
  if (n % 2 === 1) {
    return mergedNums[Math.floor(n / 2)];
  }
  // 如果数组长度为偶数,则中位数就是中间两个数的平均值
  else {
    const mid1 = Math.floor(n / 2 - 1);
    const mid2 = Math.floor(n / 2);
    return (mergedNums[mid1] + mergedNums[mid2]) / 2;
  }
};

结语

通过上述讲解,相信您已经对「正序数组的中位数」问题有了更深入的理解。希望这篇文章能够帮助您在LeetCode的征程中更进一步。