算法/编程练习:两个有序数组的中位数

2024-09-04 18:32

本文主要是介绍算法/编程练习:两个有序数组的中位数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

算法/编程练习:两个有序数组的中位数

题目来自LeetCode:
https://leetcode-cn.com/problems/median-of-two-sorted-arrays/

题目:

给定两个大小为 n1 和 n2 的有序(升序)数组 nums1 和 nums2 ,
找出这两个有序数组的中位数mid。
要求算法的时间复杂度为 O(log(m + n))。
例如,
输入:  nums1 = [1, 3, 5, 7, 9],  nums2 = [2, 4, 6, 8, 10, 11]
输出:  mid=6

思路:

记总的数组长度为 N = n1 + n2,则两个数组中小于等于mid的数有 N_lef = int(N/2)个 。
假设用索引 idx1 将 nums1 分为左右两部分,用索引 idx2 将 nums2 分为左右两部分,
若此时 nums1 和nums2的左边部分共同构成 mid 的左边,
nums1 和 nums2 的右边部分共同构成 mid 的右边,
那么 idx1 和 idx2 应满足等量约束 idx2 + idx1 + 1 = N_left。
根据中位数的定义,nums1 左边部分的最大值不能大于 num2 右边部分的最小值,
nums2 的切分同理。
因此只需要从 nums1 的最大索引开始遍历,找出 合适的 idx1 和 idx2 即可。  即:
# idx1把nums1分为左右两部分:
nums1_left = nums1[0:idx1+1]
nums1_right = nums1[idx1+1:]
# idx2把nums2分为左右两部分:
nums2_left = nums2[0:idx2]
nums2_right = nums2[idx2:]
# 能正确划分nums1和nums2从而找到mid的idx1和idx2应满足
idx2 = N_left - (idx1+1) # 且
nums1[idx1] <= nums2[idx2]

Python代码:

def Find2OrderedListMid(nums1, nums2):if not isinstance(nums1, list) or not isinstance(nums2, list):print('请输入两个列表!')return None​n1, n2 = len(nums1), len(nums2)N = n1 + n2N_left = int(N/2) # 合并数列中,中位数前面的数的个数odd = False if N % 2 == 0 else True# 代码简化处理,不考虑有数组长度为0的情况下if n1 == 0 or n2 == 0:print('需要保证两个数组的长度均大于0!')return None​​# 保持nums1的长度小于等于nums2if n1 > n2:nums1, nums2 = nums2, nums1n1, n2 = len(nums1), len(nums2)​idx1 = n1-1idx2 = N_left - (idx1+1)# 注意这里idx2的最大取值为n2-1,原因在于限制了n1 <= n2while nums1[idx1] > nums2[idx2] and idx1 > -1 and idx2 < n2-1:idx1 -= 1idx2 += 1if odd:    # odd为True时有两种情况:nums1的数全分配到左边或左右都有# (由于odd为True时必有n1<n2,因此nums2的数不可能全部分配到左边)if idx1 == n1-1: # nums1的数全分配到左边mid = nums2[idx2]else:mid = min(nums1[idx1+1], nums2[idx2])else:# odd为False时计算左边部分最大值,有三种情况if idx1 == -1: # nums1的数全部分配到右边max_left = nums2[idx2-1]elif idx2 == 0: # nums2的数全部分配到右边max_left = nums1[idx1]else:max_left = max(nums1[idx1], nums2[idx2-1])# odd为False时计算右边最小值,有两种情况# (由于N为偶数且n1 <= n2,因此当nums2的数全部分配到左边时,实际上n1 == n2,#  计算中位数时也要取nums2最后一个值)if idx1 == n1-1: # nums1的数全分配到左边min_right = nums2[idx2]else:min_right = min(nums1[idx1+1], nums2[idx2])​mid = (max_left + min_right) / 2return mid
​
​
if __name__ == '__main__':    nums1 = [1, 3, 5, 7, 9]nums2 = [2, 4, 6, 8, 10, 11]print(Find2OrderedListMid(nums1, nums2))

欢迎关注公众号:一本正经d胡说
Genlovy562

这篇关于算法/编程练习:两个有序数组的中位数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1136698

相关文章

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键

AOP编程的基本概念与idea编辑器的配合体验过程

《AOP编程的基本概念与idea编辑器的配合体验过程》文章简要介绍了AOP基础概念,包括Before/Around通知、PointCut切入点、Advice通知体、JoinPoint连接点等,说明它们... 目录BeforeAroundAdvise — 通知PointCut — 切入点Acpect — 切面

C#异步编程ConfigureAwait的使用小结

《C#异步编程ConfigureAwait的使用小结》本文介绍了异步编程在GUI和服务器端应用的优势,详细的介绍了async和await的关键作用,通过实例解析了在UI线程正确使用await.Conf... 异步编程是并发的一种形式,它有两大好处:对于面向终端用户的GUI程序,提高了响应能力对于服务器端应

Java中数组与栈和堆之间的关系说明

《Java中数组与栈和堆之间的关系说明》文章讲解了Java数组的初始化方式、内存存储机制、引用传递特性及遍历、排序、拷贝技巧,强调引用数据类型方法调用时形参可能修改实参,但需注意引用指向单一对象的特性... 目录Java中数组与栈和堆的关系遍历数组接下来是一些编程小技巧总结Java中数组与栈和堆的关系关于

C# async await 异步编程实现机制详解

《C#asyncawait异步编程实现机制详解》async/await是C#5.0引入的语法糖,它基于**状态机(StateMachine)**模式实现,将异步方法转换为编译器生成的状态机类,本... 目录一、async/await 异步编程实现机制1.1 核心概念1.2 编译器转换过程1.3 关键组件解析

Spring Boot配置和使用两个数据源的实现步骤

《SpringBoot配置和使用两个数据源的实现步骤》本文详解SpringBoot配置双数据源方法,包含配置文件设置、Bean创建、事务管理器配置及@Qualifier注解使用,强调主数据源标记、代... 目录Spring Boot配置和使用两个数据源技术背景实现步骤1. 配置数据源信息2. 创建数据源Be

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin