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

2023-11-15

二分+递归

如果某个有序数组长度是奇数,那么其中位数就是中间元素;如果长度是偶数,那么中位数就是中间两个数字的平均值.

假设两个有序数组的长度分别为 mn,由于两个数组长度之和 m+n 的奇偶不确定,为了简化代码,在合并后的数组找到第 (m+n+1)/2 个元素,和第 (m+n+2)/2 个元素(这里的 / 指的是整除),然后求两者平均值. 若 m+n 为偶数,那么两者平均值刚好是中位数;若 m+n 为奇数,那么 (m+n+1)/2(m+n+2)/2 的值相等,相当于两个相同的数字相加再除以 2,还是中位数本身.

可以实现一个函数 findKth(k),返回两个有序数组合并后的第 k 个元素,最终答案为 findKth((m+n+1)/2)findKth(m+n+2)/2 的平均值.

具体实现 findKth(k) 函数,需要对参数 k 进行二分处理:

  1. 分别在 nums1nums2 中找到各自的第 k/2 个元素,并比较它们的大小.
  2. 如果 nums1 中的第 k/2 个元素更小,说明原 nums1 的前 k/2 个元素都不是合并后的第 k 个元素(可以参考后面的举例). 因此可以忽略 nums1 中的前 k/2 个元素,继续求解在 nums1 的剩余部分和 nums2 合并后的第 k-k/2 个元素.
  3. 如果 nums2 中第 k/2 个元素更小,同理忽略 nums2 中的前 k/2 个元素,继续求解在 nums1nums2 的剩余部分合并后的第 k-k/2 个元素.

举例说明,假设 nums1=[1,3,6,9], nums2=[2,4,5,8], k=4 .

k/2=2,分别找 nums1nums2 的第 2 个元素,nums1 的第 2 个元素是 3nums2 的第 2 个元素是 4,由于 3<4,所以 nums1 中的前两个元素 1,3 在合并之后的数组中一定会排在第 4 个数之前,接下来将问题变成,nums1=[6,9], nums2=[2,4,5,8], k=2k 的规模减半,可以递归求解.

特殊情况: 如果 nums1 的长度小于 k/2,则可直接忽略 nums2 的前 k/2 个元素,反之亦然. 比如 nums1=[3], nums2=[2,4,5,6,7], k=4,分别在 nums1nums2 中找第 k/2=2 个数字,而 nums1 中只有 1 个数字,则可以直接忽略 nums2 中的前 2 个数字,因为最终答案是合并后数组的第 4 个数字,即使 nums1 中的数非常小, nums2 的前 2 个数字在合并之后也最多只能排在第 3 位.

递归终止条件:

  1. nums1nums2 为空时,直接返回非空数组的第 k 个元素即可.
  2. k=1 时,直接比较 nums1nums2 的第 1 个元素大小即可.

k 的规模不断减半,因此时间复杂度为 O ( l o g ( m + n ) ) O(log(m+n)) O(log(m+n)).

class Solution {
public:
    double findKth(vector<int>& nums1,vector<int>& nums2,int pos1,int pos2,int k){
        //返回两个有序数组nums1(从pos1下标开始),nums2(从pos2下标开始)合并后的第k个元素
        if(pos1>=(int)nums1.size()) return nums2[pos2+k-1];
        if(pos2>=(int)nums2.size()) return nums1[pos1+k-1];
        if(k==1) return nums1[pos1]<=nums2[pos2]?nums1[pos1]:nums2[pos2];

        int midVal1=pos1+k/2-1<(int)nums1.size()?nums1[pos1+k/2-1]:INT_MAX;
        int midVal2=pos2+k/2-1<(int)nums2.size()?nums2[pos2+k/2-1]:INT_MAX;

        if(midVal1<=midVal2) return findKth(nums1,nums2,pos1+k/2,pos2,k-k/2);
        else return findKth(nums1,nums2,pos1,pos2+k/2,k-k/2);
    }

    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m=nums1.size(),n=nums2.size();
        return 1.0*(findKth(nums1,nums2,0,0,(m+n+1)/2)+findKth(nums1,nums2,0,0,(m+n+2)/2))/2.0;
    }
};

个人 LeetCode 代码仓库地址:MyLeetCode,记录刷题成长之路,欢迎各位小伙伴们多多 star ~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LeetCode 4 - 寻找两个正序数组的中位数 的相关文章

  • php图片居中显示图片,CSS实现图片居中的三种方式

    在我们的WEB前端css开发过程中 我们避免会遇到让图片居中的情况 为了网页美观以及用户的体验 我们有时候就要让图片居中 那么我们也都知道图片居中的方法有很多 今天我们就给大家详细介绍下CSS实现图片居中的三种方式 1 利用display
  • Docker入门命令

    文章目录 1 安装Docker 2 搜索 下载镜像 3 查询本地镜像 4 启动镜像到容器 5 查询已启动镜像 容器 6 进入容器环境 7 创建镜像 7 1 基于已有镜像的容器创建 7 2 基于本地模板导入 7 3 基于Dockerfile创
  • AI绘图:教你几个提示词 100%生成美丽小姐姐

    许多常用提示对于确保高质量的成像结果至关重要 我们将教您一些基本的提示词和设置 以节省您在初始探索过程中的时间 本次用到的模型ChilloutMix 基础设置 默认设置包括图片 大小 512 x 512 采样器 DPM SDE Karras

随机推荐

  • 逆序栈(使用递归)

    题目 一个栈依次压入1 2 3 4 5那么从栈顶到栈底分别为5 4 3 2 1 将这个栈转置后 从栈顶到栈底为1 2 3 4 5 也就是实现了栈中元素的逆序 请设计一个算法实现逆序栈的操作 但是只能用递归函数来实现 而不能用另外的数据结构
  • springBoot添加自定义拦截器

    文章目录 前言 步骤如下 首先新建一个自己的拦截器 其次 把自己的拦截器注册到spring中 让其生效 前言 新的项目需要校验用户是否登录 在springBoot项目中添加一个自定义的拦截器拦截到所有请求进行逻辑判断 步骤如下 首先新建一个
  • 资讯汇总230429

    230429 11 44 大华股份 重点投入大模型和多模态方向 会持续按需扩容算力 大华股份在业绩说明会表示 GPT 的发展具有里程碑式的意义 公司会重点投入大模型和多模态方向 过去在大模型领域的算法和工程能力已经有一定的积累 先进技术研究
  • 内行看门道:看似“佛系”的《QQ炫舞手游》,背后的音频技术一点都不简单

    欢迎大家前往腾讯云 社区 获取更多腾讯海量技术实践干货哦 本文由腾讯游戏云发表于云 社区专栏 内行看门道 看似 佛系 的 QQ炫舞手游 背后的音频技术一点都不简单 3月14日 腾讯旗下知名手游 QQ炫舞 正式上线各大应用商店 并迅速登上Ap
  • 卡尔曼滤波与目标跟踪(由cv模型的kf推理到CTRV模型的radar与lidar))(一)

    引用AdamShan 引用知乎陈光 基于cv模型的行人状态预测 卡尔曼滤波与目标追踪 卡尔曼的理论 一 初始化 我们认为小车在第1秒时的状态x与测量值z相等 二 预测 Prediction 完成初始化后 我们开始写Prediction部分的
  • Ubuntu20.04安装各种库----简洁版

    目录 Eigen3 Sophus Pangolin Ceres g2o 建议先装anaconda再装ros python opencv啥该有的都有了 下面仅仅安装ros没有的库 Eigen3 作用 线性代数开源库 提供了有关线性代数 矩阵和
  • 汽配企业如何利用MES管理系统解决生产防错难题

    汽车配件制造业是一个高效率 低成本 高质量的生产领域 但同时也面临着一系列的挑战 其中最为突出的挑战之一是如何在生产过程中避免错误 提高产品的合格率 本文将介绍汽车配件的制造特点以及如何通过MES管理系统解决方案实现生产防错 从而提高产品合
  • 爬虫逆向(js逆向)

    异步爬虫的实现方式 线程池 多任务的异步协程 多线程 生产者消费者模型 线程池 前提 from flask import Flask render template from time import sleep app Flask name
  • 【NLP】文本聚类和主题建模

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • Chrome浏览器更新之后在开发者工具中查看格式化后的js不显示行号问题

    最近更新了谷歌浏览器 然后在调试代码的时候发现一个问题 就是当js代码是压缩后的 将其格式化之后就只显示压缩之前的行号了 如下 未格式化的 格式化之后 这样就很无语了 突然没有了行号就很不习惯了 经过在浏览器设置里面一番找之后终于找到设置这
  • 微信公众号开发(一)——开发模式接入,消息的接收与响应

    1 想自己开一个公众号 先学习一下用 Java 进行微信公众号的开发 微信公众号的管理有开发模式和编辑模式两种 两者是互斥的 腾讯是这么讲的 编辑模式 编辑模式指所有的公众号运营者都可以通过简单的编辑 设置 按关键字回复 等功能 您可以设定
  • python 打包成可执行文件

    文章目录 pyinstaller 另外一个打包工具Nuitka 常见命令选项 工具很多 只说两个 pyinstaller 网上很多人说 pyinstaller 打包慢啊 文件大啊 这那这那的 可能是我还没理解别的工具的妙用 我发现 pyin
  • Unsupported major.minor version 52.0 版本不支持问题

    摘自 https blog csdn net qq 36769100 article details 78880341 Unsupported major minor version 52 0 这个错误网上一百度一大堆 我就简单的记一下 直
  • 从github上下载下来的c++代码用vs或QTCreator运行起来(Cmake)

    初学C 从github上下载了一份源码 不知道怎么运行 特此来记录一下 源码下载下来如图所示 1 用VS运行的方法 1 文件里有CMake 需要我们有CMake工具来构建 所以第一步就是下载CMake 下载链接 Download CMake
  • 微信小程序tab切换,可滑动切换,导航栏跟随滚动实现

    微信小程序tab切换 可滑动切换 导航栏跟随滚动实现 简介 看到今日头条小程序页面可以滑动切换 而且tab导航条也会跟着滚动 点击tab导航 页面滑动 切导航栏也会跟着滚动 就想着要怎么实现这个功能 像商城类商品类目如果做成左右滑动切换类目
  • 关于:Google Chrome 官方下载地址

    1 官方在线安装版 Google Chrome 网络浏览器https www google cn intl zh CN chrome 2 官方离线安装版
  • 五大学科竞赛(二)NIOP全国青少年信息学奥林匹克分区联赛竞赛大纲

    一 初赛内容与要求 表示普及组不涉及 以下同 计 基 算 本 机 常 的 识 诞生与发展 特点 在现代社会中的应用 计算机系统的基本组成 计算机的工作原理 计算机中的数的表示 计算机信息安全基础知识 计算机网络 计 基 算 本 机 操 的
  • IDEA使用JDBC连接MySQL数据库详细教程

    文章目录 创建项目 导入驱动 让导入的驱动生效 注册数据库驱动 连接数据库 创建项目 首先需要保证你已经成功安装mysql和下载连接MySQL数据库的驱动 在IDEA里面创建一个java项目 选择创建Java项目 JDK这里选择1 8 直接
  • 二进制文件与文本文件详解

    二进制文件 定义 二进制文件就是把内存中的数据按其在内存中存储的形式原样输出到磁盘中存放 即存放的是数据的原形式 二进制文件是包含在 ASCII 及扩展 ASCII 字符中编写的数据或程序指令的文件 一般是可执行程序 图形 声音等文件 有自
  • LeetCode 4 - 寻找两个正序数组的中位数

    二分 递归 如果某个有序数组长度是奇数 那么其中位数就是中间元素 如果长度是偶数 那么中位数就是中间两个数字的平均值 假设两个有序数组的长度分别为 m 和 n 由于两个数组长度之和 m n 的奇偶不确定 为了简化代码 在合并后的数组找到第