返回

算法修炼场:寻找两个正序数组的中位数,入门不迷路!

前端

大家好,欢迎来到「每日 LeetCode」系列。我是你们的算法修炼导师,今天我们将携手攻克 LeetCode 第 4 题:寻找两个正序数组的中位数 。在本文中,我将通过独到的视角,带你领略算法的魅力,让你在算法修炼的道路上畅通无阻。

剖析算法核心

这道题的目的是找到两个正序排列数组的中位数 。中位数是指一个集合中所有数按从小到大排列后的中间数,若集合中元素个数为奇数,则中位数为该中间数;若元素个数为偶数,则中位数为两个中间数的平均值。

本题中给定的两个数组是正序排列的,这为我们提供了重要线索。为了高效地寻找中位数,我们采用归并排序 的思想,将两个数组合并为一个有序数组,然后从中提取中位数。

分步征服,逐层递进

算法的关键步骤如下:

  1. 计算两个数组合并后的总长度: 设两个数组长度分别为 m 和 n,合并后总长度为 m + n。

  2. 初始化两个指针,分别指向两个数组的首元素: 指针 i 指向数组 1,指针 j 指向数组 2。

  3. 逐一比较两个指针指向的元素:

    • 如果 i 指向的元素小于或等于 j 指向的元素,则将 i 指向的元素添加到合并后的数组中,并 i++。
    • 否则,将 j 指向的元素添加到合并后的数组中,并 j++。
  4. 重复步骤 3,直至两个指针均指向 null: 此时,合并后的数组已经有序。

  5. 根据合并后数组的长度计算中位数:

    • 如果总长度 m + n 为奇数,则中位数为合并后数组中间位置的元素。
    • 如果总长度 m + n 为偶数,则中位数为合并后数组中间位置的两个元素的平均值。

代码示例,一览无遗

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    // 1. 计算合并后总长度
    int m = nums1.length;
    int n = nums2.length;
    int totalLength = m + n;

    // 2. 初始化指针
    int i = 0;
    int j = 0;
    int[] merged = new int[totalLength];

    // 3. 逐一比较两个指针指向的元素
    for (int k = 0; k < totalLength; k++) {
        if (i < m && (j >= n || nums1[i] <= nums2[j])) {
            merged[k] = nums1[i++];
        } else {
            merged[k] = nums2[j++];
        }
    }

    // 4. 计算中位数
    double median;
    if (totalLength % 2 == 0) {
        median = (double) (merged[totalLength / 2] + merged[totalLength / 2 - 1]) / 2;
    } else {
        median = merged[totalLength / 2];
    }

    return median;
}

展望未来,算法进阶

LeetCode 题库的题目千变万化,想要在算法修炼的道路上越走越远,除了掌握基本算法,我们还需要:

  • 理解算法本质: 深刻理解算法的工作原理,才能在不同场景灵活运用。
  • 勤加练习: 熟能生巧,只有不断练习,才能提升算法解决问题的效率和准确性。
  • 探索算法多样性: 算法种类繁多,掌握多种算法技巧,才能应对不同的问题类型。

结语

通过对 LeetCode 第 4 题的剖析,相信你对寻找两个正序数组的中位数有了更深刻的理解。算法修炼是一段充满挑战却也收获满满的旅程。让我们携手前行,在算法的世界里不断探索,解锁更精彩的篇章!