Leetcode算法题:两个有序数组求中位数

  • 要求时间复杂度为O(log(m+n))

思路:

  1. 暴力解决:合并数组并排序,简单且一定能实现,时间复杂度O(m+n)
  2. 由于两个数组已经排好序,可一边排序一边合并,用时为第一种的一半,时间复杂度依然为O(m+n)
  3. 由题目,只需要找中位数,即中位数两侧的元素并不需要完全排序,且两数组长度已知且有序,合并后中位数的索引是固定的,所以只要找到这一个或计算中位数的两个数的索引即可,既然为查找,可用二分查找,即可实现时间复杂度为O(log(m+n))

解决方案:

  • 将两数组分别分为左右两部分,左侧的两部分即为包含中位数的左侧,右侧即为可能包含中位数的右侧。由于一个数组的划分位置确定,另一个数组划分位置即可确定,所以只需使用二分查找在一个数组中查找到正确的划分位置就行了。

  • 为了防止一个数组中确定界限后另一个数组的分界线数组越界,直接在取小数组作为查找目标。

  • 递归查找很简单,但是索引在边界时情况非常复杂,且python中-1索引也可以取到,花了很久才找到问题所在,因此在此记录下来。


def findMedianSortedArrays(nums1, nums2):def mid_index(left, right):return (left + right) // 2# 以下称第一个数组为A,第二个数组为Bdef findMedianSortedArraysSorted(short_nums, m, long_nums, n):is_odd = (m + n) % 2 mid = (m + n - 1) // 2if m == 0:if is_odd:return long_nums[mid]else:return float(long_nums[mid] + long_nums[mid + 1]) / 2left = 0right = m - 1i = mid_index(left, right)while left <= i <= right:j = mid - (i + 1)# 若A数组左侧最大元素大于B数组右侧最小元素,中位索引左移if i > 0 and short_nums[i] > long_nums[j + 1]:right = ii = mid_index(left, right)# 若B数组左侧最大元素大于B数组右侧最小元素,中位索引右移elif i < m - 1 and long_nums[j] > short_nums[i + 1]:left = i + 1i = mid_index(left, right)# 从0索引开始查找,查找并未结束# 其实只有数组长度为2时才会出现这种情况elif i == 0 and m > 1 and long_nums[j] > short_nums[i + 1]:left = i + 1i = mid_index(left, right)# 达成结束条件else:if i == 0:# 该数组最小值比在另一个数组中可能的中位值大# 即整个数组所有元素都应该放在右侧if short_nums[i] > long_nums[j + 1]:max_left = long_nums[j + 1]if j + 3 <= n:min_right = min(short_nums[i], long_nums[j + 2])else:min_right = short_nums[i]else:# 只出现在两个只有一个元素,且A数组元素小于B数组元素的情况下# 应该可以合并到其他情况中,但是脑子不够用了,希望有人可以提意见if j == -1:max_left = short_nums[i]min_right = long_nums[j + 1]else:max_left = max(short_nums[i], long_nums[j])if m > 1:min_right = min(short_nums[i + 1], long_nums[j + 1])else:min_right = long_nums[j + 1]# 检索到了最后一个元素elif i == m - 1:# 大坑,两数组等长时,检索到末端时j的值为-1# python列表的-1索引可以取到最后一个元素,debug才找到问题if j == -1:max_left = short_nums[i]min_right = long_nums[j + 1]# A数组最大值小于B数组中位数elif short_nums[i] < long_nums[j]:max_left = long_nums[j]min_right = long_nums[j + 1]else:max_left = max(short_nums[i], long_nums[j])min_right = long_nums[j + 1]# 在中间位置找到正确的中位数else:max_left = max(short_nums[i], long_nums[j])min_right = min(short_nums[i + 1], long_nums[j + 1])if is_odd:return max_leftelse:return float(max_left + min_right) / 2a = len(nums1)b = len(nums2)if a > b:return findMedianSortedArraysSorted(nums2, b, nums1, a)else:return findMedianSortedArraysSorted(nums1, a, nums2, b)

Leetcode算法题:两个有序数组求中位数相关推荐

  1. 算法题:两个有序数组求中位数

    leetcode上遇到的一道题,感觉很有意思 因为要求O(log(m+n)),所以第一反应时用二分来找,但是该怎么用二分呢? 数组A,B分别有序,我们可以先找到数组A中的一条分界线i,使得数组A分为A ...

  2. 【两个有序数组求中位数】

    /* 两个有序数组求中位数问题; 这个题有很多方法: 方法一:排序,找到中位数: 方法二:归并排序的思想 方法三:转换成求第k小值   */ /* 思路:使用二分查找,时间复杂度为log(m+n). ...

  3. 两个有序数组求中位数的三种解法

    寻找两个有序数组的中位数(附上三种解法)_BoCong-Deng的博客-CSDN博客_两个有序数组求中位数

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

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

  5. leetcode 4. 寻找两个有序数组的中位数,c语言

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

  6. 【LeetCode】寻找两个有序数组的中位数【性质分析+二分】

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

  7. [leetcode] 4 寻找两个有序数组的中位数(二分+递归查找第K小数)(重要)

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

  8. C++leetcode找出两个有序数组的中位数(2)

    给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 如果不考虑复杂度的话这个题目很简单:将两 ...

  9. LeetCode 4. 寻找两个有序数组的中位数(二分查找,难)

    文章目录 1. 题目 2. 解题 2.1 合并数组 2.2 优化2.1解法,双指针 2.3 二分法(找第k个数) 2.4 切分法 1. 题目 给定两个大小为 m 和 n 的有序数组 nums1 和 n ...

最新文章

  1. Confluence 6 用户目录图例 - 连接 Jira 和 Jira 连接 LDAP
  2. python 时间字符串和时间戳之间的转换
  3. [Automation] 自动化测试工具和测试框架大集合
  4. 热电偶单片机代码c语言,基于STC12C5A60S2单片机的恒温箱设计-LCD1602-热电偶(电路图+程序源码)...
  5. Direct2D (2) : 基本图形命令测试
  6. NET问答: 如何实现读写 file 的时候不用锁模式 ?
  7. java利用模板发送邮件_使用JavaMail实现发送模板邮件以及保存到发件箱
  8. 学习过程中的一些细节
  9. 冲浪科技获Ventech China数百万美元天使轮融资,发力自动驾驶行业
  10. Easypoi 报表模板设置
  11. 魔客吧php登录界面模板,精仿魔客吧网站模板discuz模板_带VIP购买等多个插件
  12. QT5.5.0+VS2013(64位)+hidapi 的USB继续深究之VID和PID
  13. html图片右边加竖线,插入Html竖线代码
  14. IOS成长之路-使用系统默认声音、震动
  15. oracle 数据库中order by 的一些高级用法
  16. JFreeChart| JFreeChart组合图表(Combined Charts)
  17. windows system info
  18. 一加7t人脸识别_一加7T新机设计图发布 这款手机的外观设计如何
  19. 高级加密标准 (AES) 和安全断言标记语言 (SAML) 的 Web 安全
  20. 子曾经说过,在有些问题上,我们决不能退步

热门文章

  1. 高级WIN2K ROOTKIT检测技术
  2. Python3网络爬虫开发实战,Scrapy 爬取新浪微博
  3. 华为v10的android版本,荣耀V10 P 版本(EMUI 9.0+Android 9.0) 正式版 9.0.0.125 发布说明...
  4. 前端的主流组件库你知道有那些吗?是否都会用呢?
  5. 生活感悟----关于活着
  6. java对象数组排序_如何在Java中对对象数组进行排序?
  7. 图片与文字垂直居中的方法
  8. heidisql连接远程数据库_Heidisql如何连接sql server数据库并做增删改操作?
  9. Directory.CreateDirectory();创建多级文件夹
  10. UnityShader_倒影,水波倒影(代码已更新)(2)