题目描述:

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

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

方法一:根据定义,合并、排序以后取中位数(时间复杂度不符合要求)
这应该是最简单直接的做法,即根据定义来做。考虑如下两种情况:
情况 1:如果合并以后的数组的长度是偶数,中位数有 2 个,此时取它们的平均值;
情况 2:如果合并以后的数组的长度是奇数;中位数有 1 个,把这个值返回即可。
说明:这个解法虽然不符合题目要求,但是是常规思路。并且它的优点也很显著:即在输入数组不是有序数组的时候,这个算法依然有效,因此如果这一题出现在面试中,向面试官提到这个最简单的思路,我觉得也是有必要的(一定要把它的这个优点连带说出来)。代码如下

from typing import Listclass Solution:def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:m = len(nums1)n = len(nums2)nums1.extend(nums2)nums1.sort()if (m + n) & 1:return nums1[(m + n - 1) >> 1]#右移一位相当于除以2作者这样做的目的是为了防止数据溢出,但是python好像不存在溢出else:return (nums1[(m + n - 1) >> 1] + nums1[(m + n) >> 1]) / 2

这段代码是基于二分查找的归并排序算法。

将两个数据合并后找到一条线将数组一分为二,假设数组1左边元素的个数是i,数组1右边元素的个数为j。i和j满足以下关系式:

j=m+n+1/2    - i其中m和n分别数组1和数组2的元素个数。则只需从数组1中查找到索引i即可。

在查找过程中主要有以下两种情况

(1)mums2[j-1]>nums1[i]即数组2右边的最小值比数组1左边的最大值还要大,此时需要扩大数组1的左半部分即i+1

(2)mums1[i-1]>nums2[j]即数组1左边的最大值比数组2右边的最小值还要大,此时需要缩小数组1的左半部分即i不让i-1是为了防止数组越界

from typing import Listclass Solution:def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:# 为了让搜索范围更小,我们始终让 num1 是那个更短的数组,PPT 第 9 张if len(nums1) > len(nums2):# 这里使用了 pythonic 的写法,即只有在 Python,中可以这样写# 在一般的编程语言中,得使用一个额外变量,通过"循环赋值"的方式完成两个变量的地址的交换nums1, nums2 = nums2, nums1# 上述交换保证了 m <= n,在更短的区间 [0, m] 中搜索,会更快一些m = len(nums1)n = len(nums2)# 使用二分查找算法在数组 nums1 中搜索一个索引 i,PPT 第 9 张left = 0right = m# 因为 left_total 这个变量会一直用到,因此单独赋值,表示左边粉红色部分一共需要的元素个数left_total = (m + n + 1) >> 1while left < right:# 尝试要找的索引,在区间里完成二分,为了保证语义,这里就不定义成 mid 了# 用加号和右移是安全的做法,即使在溢出的时候都能保证结果正确,但是 Python 中不存在溢出# 参考:https://leetcode-cn.com/problems/guess-number-higher-or-lower/solution/shi-fen-hao-yong-de-er-fen-cha-zhao-fa-mo-ban-pyth/i = (left + right) >> 1j = left_total - i# 如果 nums1 左边最大值 > nums2 右边最小值if nums2[j - 1] > nums1[i]:# 这个分支缩短边界的原因在 PPT 第 8 张,情况 ①left = i + 1else:# 这个分支缩短边界的原因在 PPT 第 8 张,情况 ②# 【注意】:不让它收缩的原因是讨论 nums1[i - 1] > nums2[j],i - 1 在数组的索引位置,在 i = 0 时越界right = i# 退出循环的时候,交叉小于等于一定关系成立,那么中位数就可以从"边界线"两边的数得到,原因在 PPT 第 2 张、第 3 张i = leftj = left_total - left# 边界值的特殊取法的原因在 PPT 第 10 张nums1_left_max = float('-inf') if i == 0 else nums1[i - 1]nums1_right_min = float('inf') if i == m else nums1[i]nums2_left_max = float('-inf') if j == 0 else nums2[j - 1]nums2_right_min = float('inf') if j == n else nums2[j]# 已经找到解了,分数组之和是奇数还是偶数得到不同的结果,原因在 PPT 第 2 张if (m + n) & 1:return max(nums1_left_max, nums2_left_max)else:return (max(nums1_left_max, nums2_left_max) + min(nums1_right_min, nums2_right_min)) / 2

转自:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/he-bing-yi-hou-zhao-gui-bing-guo-cheng-zhong-zhao-/

leetcode4两数相加相关推荐

  1. leetCode刷题 2. 两数相加

    原题链接: leetcode-cn.com/problems/ad- 题目描述 给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你 ...

  2. 【每日一算法】两数相加

    微信改版,加星标不迷路! 每日一算法-两数相加 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两 ...

  3. 【前端来刷LeetCode】两数之和与两数相加

    大部分玩前端的小伙伴,在算法上都相对要薄弱些,毕竟调样式.调兼容就够掉头发的了,哪还有多余的头发再去折腾. 确实在前端中需要使用到算法的地方是比较少,但若要往高级方向发展,算法的基本功就非常重要啦.对 ...

  4. [Swift]LeetCode2. 两数相加 | Add Two Numbers

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...

  5. LeetCode 2 两数相加

    给定两个非空链表来代表两个非负数,位数按照逆序方式存储,它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入:(2 - ...

  6. 计算机组成原理两数相加指令,计算机组成原理复习题

    27. 一个16K×32位的存储器,其地址线和数据线的总和是 . A.48 B.46 C.36 答案:B 28.由于磁盘上的内部同心圆小于外部同心圆,则对其所存储的数据量而言, . A.内部同心圆大于 ...

  7. js 数字相加_Python练习:解题 - 两数相加(JS, TS, PY3版)

    两数相加 题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新 ...

  8. LeetCode 2 两数相加(链表)

    题目要求: 给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入 ...

  9. python 链表两数相加

    | 两数相加 给你两个 非空 的链表,表示两个非负的整数.它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字. 请你将两个数相加,并以相同形式返回一个表示和的链表. 你可以假设 ...

最新文章

  1. C++:while(getline())函数
  2. 大神们,这是网易邮箱服务器的报错信息,能分析出来什么?
  3. C# .NET 根据Url链接保存Image图片到本地磁盘
  4. DeepID:Python基于Caffe的DeepID2实现人脸识别的简介、实现之详细攻略
  5. 有三个数a,b,c,要求按大小顺序输出。
  6. GIS应用技巧之世界各国矢量获取途径
  7. Jmeter脚本录制 badboy的下载安装教程
  8. 使用TypeScript两年后,还值得吗?
  9. python中的wait和notify
  10. 平面设计师主要做什么?平面设计的工作内容有哪些?
  11. vscode遇到无法访问此网站问题的两种解决方法
  12. 《转》Vmware vSphere常见问题汇总
  13. 电脑解锁后黑屏有鼠标_电脑开机后,显示屏黑屏只有鼠标箭头,怎么回事
  14. 谷歌 地图 android studio,Android Studio百度地图开发(一)
  15. android 小q机器人,腾讯小Q机器人第二代,是机器人也是家人
  16. 泊松分布,指数分布介绍以及其联系与区别
  17. Rust 中的指针:Box、Rc、Cell、RefCell
  18. 计算机毕业论文会计,会计毕业论文6000字
  19. Springboot父子工程搭建到部署
  20. 登录搜狐邮箱并发送邮件的3中方法

热门文章

  1. 如何证明在素数p和2p之间存在另一个素数呢?简单却不完备的证明
  2. medical research
  3. virtualbox4 剪贴板(共享粘贴板)失效之原因
  4. 万字长文浅析SpringCould微服务负载均衡框架Ribbon源码(字多慎入)
  5. Shell 环境中的预定义变量
  6. 用Docker打造多版本PHP运行环境
  7. C#中dynamic的正确用法 以及 typeof(DynamicSample).GetMethod(Add);
  8. 配置管理小报100629:我是项目组成员,事情比较急,按流程需要项目经理批准,但项目经理不在怎么办?...
  9. » Markdown/reST 编辑器 ReText 3.0 发布 Wow! Ubuntu
  10. 标题:ASP.NET几种进行性能优化的方法及注意问题