当前位置: 首页 > article >正文

LeetCode - 4 寻找两个正序数组的中位数

题目来源

4. 寻找两个正序数组的中位数 - 力扣(LeetCode)

题目描述

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

算法的时间复杂度应该为 O(log (m+n)) 。

示例 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

提示

  • nums1.length == m
  • nums2.length == n
  • 0 <= m <= 1000
  • 0 <= n <= 1000
  • 1 <= m + n <= 2000
  • -10^6 <= nums1[i], nums2[i] <= 10^6

题目解析

这题目前没有想到 O(log(m+n)) 时间复杂度的解法,后面找机会看看官方题解。

我看到这题,会联想到归并排序里面合并两个有序数组的策略,而本题实际上不需要合并 nums1 和 nums2,只需要模拟合并比较过程即可。

由于我们需要找到 nums1 和 nums2 合并后有序数组的中位数,而中位数就是中间的数,因此我们可以先求出合并后数组的长度 len = nums1.length + nums2.length。

  • 如果 len 为奇数,那么中位数就是合并后数组的第 len / 2 的元素
  • 如果 len 为偶数,那么中位数就是合并后数组的第 len / 2 和 len / 2 + 1 的元素的平均数

为了代码逻辑简单,我们这里默认合并后数组的中间数有两个,分别记录于 midNum1 和 midNum2。

合并两个有序数组的过程如下:

定义一个变量 k,用于记录已经合并的元素个数,这里我们需要合并 len / 2 + 1 个数

定义变量 i 和 变量 j,分别指向 nums1 和 nums2 的索引位置,初始时都为 0。

我们需要不停地比较 nums1[i] 和 nums2[j],谁更小,则谁先被合并。

当然,也存在某个数组被先一步合并完的情况,此时需要做好越界判断。

  1. 若 i 越界,即 i >= nums1.length,则 j++
  2. 若 j 越界,即 j >= nums2.length,则 i++
  3. 若 nums1[i] <= nums2[j],则 i++
  4. 若 nums1[i] > nums2[j],则 j++

每发生一次合并,我们需要操作如下:

  1. midNum1 = midNum2
  2. 更新 midNum2 为合并的元素值

这样的话,最后 midNum1 和 midNum2 记录的就是最后被合并的两个元素值。

由于我们只合并 len / 2 + 1 次,因此最后合并的两个元素值就是完全合并后的大数组的中间两个元素值。

  • 如果 len % 2 == 0,那么结果就是 (midNum1 + midNum2) / 2
  • 如果 len % 2 != 0,那么结果就是 midNum2

C源码实现

double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
    int len = nums1Size + nums2Size;

    int i = 0;
    int j = 0;

    int midNum1 = -1;
    int midNum2 = -1;

    for (int k = 0; k <= len / 2; k++) {
        midNum1 = midNum2;
        if (i >= nums1Size) {
            midNum2 = nums2[j++];
        } else if (j >= nums2Size) {
            midNum2 = nums1[i++];
        } else if (nums1[i] <= nums2[j]) {
            midNum2 = nums1[i++];
        } else {
            midNum2 = nums2[j++];
        }
    }

    if (len % 2 == 0) {
        return (midNum1 + midNum2) / 2.0;
    } else {
        return midNum2;
    }
}

C++源码实现

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int len = nums1.size() + nums2.size();

        int i = 0;
        int j = 0;

        int midNum1 = -1;
        int midNum2 = -1;

        for (int k = 0; k <= len / 2; k++) {
            midNum1 = midNum2;
            if (i >= nums1.size()) {
                midNum2 = nums2[j++];
            } else if (j >= nums2.size()) {
                midNum2 = nums1[i++];
            } else if (nums1[i] <= nums2[j]) {
                midNum2 = nums1[i++];
            } else {
                midNum2 = nums2[j++];
            }
        }

        if (len % 2 == 0) {
            return (midNum1 + midNum2) / 2.0;
        } else {
            return midNum2;
        }
    }
};

Java源码实现

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int len = nums1.length + nums2.length;

        int i = 0;
        int j = 0;

        int midNum1 = -1;
        int midNum2 = -1;

        for (int k = 0; k <= len / 2; k++) {
            midNum1 = midNum2;
            if (i >= nums1.length) {
                midNum2 = nums2[j++];
            } else if (j >= nums2.length) {
                midNum2 = nums1[i++];
            } else if (nums1[i] <= nums2[j]) {
                midNum2 = nums1[i++];
            } else {
                midNum2 = nums2[j++];
            }
        }

        if (len % 2 == 0) {
            return (midNum1 + midNum2) / 2.0;
        } else {
            return midNum2;
        }
    }
}

Python源码实现

class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        length = len(nums1) + len(nums2)

        i = 0
        j = 0

        midNum1 = -1
        midNum2 = -1

        for k in range(length // 2 + 1):
            midNum1 = midNum2
            if i >= len(nums1):
                midNum2 = nums2[j]
                j += 1
            elif j >= len(nums2):
                midNum2 = nums1[i];
                i += 1
            elif nums1[i] <= nums2[j]:
                midNum2 = nums1[i];
                i += 1
            else:
                midNum2 = nums2[j]
                j += 1

        if length % 2 == 0:
            return (midNum1 + midNum2) / 2.0
        else:
            return midNum2

JavaScript源码实现

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number}
 */
var findMedianSortedArrays = function (nums1, nums2) {
    const len = nums1.length + nums2.length;

    let i = 0;
    let j = 0;

    let midNum1 = -1;
    let midNum2 = -1;

    for (let k = 0; k <= len / 2; k++) {
        midNum1 = midNum2;
        if (i >= nums1.length) {
            midNum2 = nums2[j];
            j++;
        } else if (j >= nums2.length) {
            midNum2 = nums1[i];
            i++;
        } else if (nums1[i] <= nums2[j]) {
            midNum2 = nums1[i];
            i++;
        } else {
            midNum2 = nums2[j];
            j++;
        }
    }

    if (len % 2 == 0) {
        return (midNum1 + midNum2) / 2;
    } else {
        return midNum2;
    }
};

http://www.kler.cn/a/283300.html

相关文章:

  • java模拟键盘实现selenium上下左右键 table中的左右滚动条实现滚动
  • 机器学习day3-KNN算法、模型调优与选择
  • Java 堆内存管理详解:`-Xms` 和 `-Xmx` 参数的使用与默认内存设置
  • 【Threejs】相机控制器动画
  • Node.Js+Knex+MySQL增删改查的简单示例(Typescript)
  • Python如何从HTML提取img标签下的src属性
  • Pytorch 自动微分注意点讲解
  • 在 MySQL 中使用 `REPLACE` 函数
  • python实现蚁群算法
  • Google 插件推荐 50 个
  • 【数据库】两个集群数据实现同步方案
  • Python配置管理工具库之hydra使用详解
  • 机器学习—线性回归算法(Linear Regression)
  • 图结构与高级数据结构的学习笔记一
  • 语言的数据访问
  • 高性能4G灯杆网关,未来智慧城市的神经中枢
  • 【LeetCode面试150】——54螺旋矩阵
  • React Hooks 的高级用法
  • LuaJit分析(八)LuaJit预编译库函数加载过程
  • 【秋招笔试】8.21华为秋招-三语言题解
  • 算法训练营|图论第4天 110.字符串接龙 105.有向图的完全可达性 106.岛屿的周长
  • 网络原理 TCP与UDP协议
  • 本地构建spotbugs,替换gradle的默认仓库地址。
  • chapter08-面向对象编程——(Object类详解)——day09
  • 【C++ Primer Plus习题】7.5
  • Docker方式部署K8s集群