参考:【分步详解】两个有序数组中的中位数和Top K问题

题目描述

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

则中位数是 2.0
示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays

思路分析

一个增序数组

要寻求一个数组的中位数,很容易让人联想到用二分法解决

对于偶数个元素的数组A,假定其元素个数为 n,下标从0开始,其中位数是 (A[(n-1)/2] + A[n/2])/2

对于偶数个元素的数组B,假定其元素个数为m,下标从0开始,其中位数是A[m/2]

隐含条件:任何一个存在中位数的数组,其中位数都会将数组分割成等长的两份,并且左边小于中位数,右边大于中位数

两个增序数组

接下来推广,从上面的结论很容易得出,对于两个增序数组A,B,如果数组A中存在一个下标 i ,数组B中存在一个下标 j ,使得 len(数组A+数组B的左边) == len(数组A+数组B的右边),并且存在一个数使得A和B的左边都比它小,A和B的右边都比它大,那这个数就是这两个增序数组的中位数。

left_part Cut right_part
A[0],A[1],…,A[i] / A[i+1],A[i+2],…,A[m-1]
B[0],B[1],…,B[j] / B[j+1],B[j+2],…,B[n-1]

用表达式来表示上面的两个条件就是

  • i+j == m-1-i + n-1-j

  • A[i] <= B[j+1] && B[j] <= A[i+1]

双数组长度的奇偶

一个数组的奇偶有两种情况,可以想象,如果考虑双数组的奇偶,将是会有 2*2 = 4种情况,这将会大大增加编程难度,那么有没有一种方法让我们不用考虑奇偶。

让数组恒为奇数

操作很简单,就是给每个元素的左右加一个字符,比如 ‘#’,长度变为2*n+1,ex:

before len after len
{1,2,3} 3 {#,1,#,2,#,3,#} 7
{4,5,6,7} 4 {#,4,#,5,#,6,#,7,#} 9

这样加的好处不光解决了奇偶的问题,还让获取元素的方法化简了,对于任何一个元素,都可以通过 现在的位置/2 得到原来的位置,比如{#,1,#,2,#,3,#}中的2,它的位置是a[3],通过 3/2 == 1,可以得到原来的位置,{1,2,3}中的a[1] == 2,{#,4,#,5,#}中的5,位置是a[3],3/2 == 1,即{4,5,6,7}中的a[1] == 5

当然这个操作并不需要在代码里实现,这里只是帮助理解

等式变换

接下来看这个等式

  • i+j == m-1-i + n-1-j

由于数组长度增加,第一个等式变为

  • i+j == 2*m+1-1-i + 2*n+1-1-j
  • i+j == 2*m-i + 2*n-j
  • i+j == m+n

由此可得出 j == m+n-i,其中 i (0~2*m)

由于 j > 0,因此可以得出 m+n-i > 0,由 i 的取值范围,最终得出此关系成立的条件是 n>m,即第二个数组的大小一定要比第一个大。

分治策略

接下来看这个等式

  • A[i] <= B[j+1] && B[j] <= A[i+1]

那么分治的策略就很明显了

如果 A[i] > B[j+1],说明A数组的左边太长了,应该向左二分

如果 B[j] > A[i+1],说明A数组的左边太短了,应该向右二分

临界点

如果 i == 0 或 j == 0 或 i == 2*m 或 j == 2*n,那么A[i+1],B[j+1]等等都不存在,此时,到达临界的数组整体可能都比另一数组中的某一值小(大),那么中值在另一数组中。

代码

#include <bits/stdc++.h>using namespace std;class Solution
{
public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2){int m = nums1.size();int n = nums2.size();if(m>n)             //保证数组1长度<数组2长度return findMedianSortedArrays(nums2,nums1);int l1 = 0,l2 = 0,r1 = 0,r2 = 0,i = 0,j = 0,imin = 0,imax = 2*m; //下标为0~2*mwhile(imin <= imax)   //存在空数组的情况,因此要有={i = (imax+imin)/2;j = m+n-i;l1 = (i == 0)?INT_MIN:nums1[(i-1)/2];r1 = (i == 2*m)?INT_MAX:nums1[i/2];l2 = (j == 0)?INT_MIN:nums2[(j-1)/2];r2 = (j == 2*n)?INT_MAX:nums2[j/2];if(l1>r2)imax = i-1;else if(l2>r1)imin = i+1;elsebreak;}return (max(l1,l2)+min(r1,r2))/2.0;}};int main()
{vector<int> a = {1,2,4,5};vector<int> b = {3};Solution Sve;cout<<Sve.findMedianSortedArrays(a,b);return 0;
}

最详解——寻找两个有序数组的中位数相关推荐

  1. 两个有序数组的中位数 python_Python寻找两个有序数组的中位数实例详解

    Python寻找两个有序数组的中位数 审题: 1.找出意味着这是一个查找算法题 2.算法复杂度log级别,就是提示你是二分查找 3.二分查找实现一般为递归 (1)递归包括递归体 (2)终止条件 思路: ...

  2. 算法--------------------寻找两个有序数组的中位数

    题目描述 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2.请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)).你可以假设 nums1 和 num ...

  3. LeetCode4. 寻找两个有序数组的中位数

    4. 寻找两个有序数组的中位数 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假 ...

  4. 20191016:(leetcode习题)寻找两个有序数组的中位数

    寻找两个有序数组的中位数 题目 大致思路 代码实现 题目 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log( ...

  5. (JS)寻找两个有序数组的中位数

    寻找两个有序数组的中位数 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 n ...

  6. Python寻找两个有序数组的中位数

    Python寻找两个有序数组的中位数 审题: 找出意味着这是一个查找算法题 算法复杂度log级别,就是提示你是二分查找 二分查找实现一般为递归 (1)递归包括递归体 (2)终止条件 思路: 定理: 有 ...

  7. 力扣寻找两个有序数组的中位数

    寻找两个有序数组的中位数 要求 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假 ...

  8. LeetCode(Python实现)—寻找两个有序数组的中位数

    4.寻找两个有序数组的中位数 题目大意 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). ...

  9. 分享一道力扣困难题~寻找两个有序数组的中位数(Java)

    目录 解题思路1 具体代码 解题思路2 具体代码 题目描述:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的 中位数 .算法的时间复杂 ...

最新文章

  1. 浅谈对html css的理解,HTML+CSS入门 CSS选择器 、属性和值浅谈
  2. 纪念机器翻译概念的诞生:重新认识瓦伦·韦弗先生
  3. 章节之外:makefile中的函数定义
  4. win10 uwp 线程池
  5. 分布式ID-数据库多主模式
  6. jquery template.js前端模板引擎
  7. Linux下rgmii接口与fpga相连,FPGA控制RGMII接口PHY芯片88E1512网络通信
  8. 教你一招用python发送QQ邮件
  9. MySQL—delete和truncate的区别
  10. Pandas 中文文档
  11. 计算机工程与网络学术会议怎么样,第七届计算机工程与网络国际会议(CENet2017)确保EI快速检索!...
  12. noip2010乌龟棋解题报告
  13. 张一鸣的心里“住着小马哥”
  14. 关键词推荐工具中的用户引导机制之三
  15. ps黑作坊终极天空大师 一键换天空终极版破解版扩展面板
  16. Eclipse语言包在官网下载不了-解决方案
  17. Win11修改Hosts文件无法保存怎么解决?
  18. D-OJ刷题日记:顺序查找 题目编号:517
  19. Good Luck in CET-4 Everybody! HDU - 1847
  20. Android仿qq邮箱账号邮件账号输入框交互

热门文章

  1. 这18节课手把手教会你入门蚂蚁区块链BAAS系统开发
  2. 入职地府后我成了人生赢家_入职地府后我成了人生赢家
  3. AdaptiveAvgPool2d理解(中网、外网整合)
  4. 锐龙r7 4750g核显什么水平 r7Pro 4750G怎么样
  5. Java实现OPC DA通信
  6. IOS版aplayer使用教程_火焰纹章:英雄电脑版手机模拟器下载及使用官方教程
  7. 【大数据哔哔集20210112】Sorry,Hbase的LSM Tree真的可以为所欲为!
  8. 傻瓜式教大家 win7怎么下载node.js
  9. 电脑上如何安装python
  10. hammer.js教程1