引言:中位数的「C位之争」

如果把数组比作排队买奶茶的队伍,中位数就是那个站在正中间的幸运儿——不需要知道所有人的位置,只需要找到那个「刚刚好」的中间位置。这个问题看似简单,却藏着算法世界的「效率密码」,尤其是当要求时间复杂度达到O(log(m+n))时,就像要求兔子不仅要跑赢比赛,还要跑出博尔特的速度!

解法等级划分

青铜解法:暴力合并的「小学生算法」

直观思路:把两个数组合并成一个大数组,像小学生合并作业本一样简单粗暴

func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {// 合并两个有序数组(像把两堆牌合并成一堆)merged := make([]int, 0, len(nums1) + len(nums2))i, j := 0, 0// 双指针合并(像两个兔子赛跑,谁小谁先走)for i < len(nums1) && j < len(nums2) {if nums1[i] < nums2[j] {merged = append(merged, nums1[i])i++} else {merged = append(merged, nums2[j])j++}}// 处理剩余元素(总有一个兔子先跑到终点)merged = append(merged, nums1[i:]...)merged = append(merged, nums2[j:]...)// 计算中位数(中间位置的幸运儿)n := len(merged)if n % 2 == 1 {return float64(merged[n/2])}return float64(merged[n/2-1] + merged[n/2]) / 2
}

复杂度分析

  • 时间复杂度:O(m+n) - 两个兔子跑完了所有路程,像乌龟一样慢
  • 空间复杂度:O(m+n) - 额外数组存储所有元素,堪称「内存土豪」

青铜程序员的痛点:当m和n都是10⁴级别时,这个算法就像让蜗牛参加马拉松——LeetCode直接给你个超时大礼包!

提交结果,好像挺快的
在这里插入图片描述

白银解法:双指针的「优化版暴力」

优化思路:不需要完整合并数组,像聪明的兔子只跑一半路程

func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {m, n := len(nums1), len(nums2)totalLength := m + nmid := totalLength / 2// 只需要记录中间位置附近的两个值prev, curr := 0, 0i, j := 0, 0for k := 0; k <= mid; k++ {prev = curr// 双指针移动(像两个兔子比赛,谁小谁前进)if i < m && (j >= n || nums1[i] < nums2[j]) {curr = nums1[i]i++} else {curr = nums2[j]j++}}if totalLength % 2 == 1 {return float64(curr)}return float64(prev + curr) / 2
}

复杂度分析

  • 时间复杂度:O((m+n)/2) - 兔子只跑了一半路程,比青铜快了一倍
  • 空间复杂度:O(1) - 只需要几个变量,堪称「空间洁癖患者福音」

边界情况专题:当一个数组为空时,就像其中一个兔子请假了,直接返回另一个数组的中位数

提交结果
在这里插入图片描述

黄金解法:二分查找的「精准制导」

核心思想:把问题转化为「寻找第k小的元素」,像用导弹精准打击目标位置

func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {// 确保nums1是较短的数组,减少二分次数(像让短腿兔子先跑)if len(nums1) > len(nums2) {return findMedianSortedArrays(nums2, nums1)}m, n := len(nums1), len(nums2)totalLeft := (m + n + 1) / 2 // +1确保奇数时取左中位数left, right := 0, mfor left <= right {// i: nums1中取前i个元素,j: nums2中取前j个元素i := left + (right - left) / 2j := totalLeft - i// 边界情况处理(兔子不能跑出跑道)nums1Left := math.MinInt32if i > 0 {nums1Left = nums1[i-1]}nums1Right := math.MaxInt32if i < m {nums1Right = nums1[i]}nums2Left := math.MinInt32if j > 0 {nums2Left = nums2[j-1]}nums2Right := math.MaxInt32if j < n {nums2Right = nums2[j]}// 二分调整(像调整望远镜焦距,直到看清目标)if nums1Left <= nums2Right && nums2Left <= nums1Right {// 找到合适的分割点if (m + n) % 2 == 1 {return float64(max(nums1Left, nums2Left))}return float64(max(nums1Left, nums2Left) + min(nums1Right, nums2Right)) / 2} else if nums1Left > nums2Right {// nums1取多了,左移right = i - 1} else {// nums2取多了,右移left = i + 1}}return 0
}// 辅助函数:取最大值
func max(a, b int) int {if a > b {return a}return b
}// 辅助函数:取最小值
func min(a, b int) int {if a < b {return a}return b
}

复杂度分析

  • 时间复杂度:O(log(min(m,n))) - 像兔子中的博尔特,速度快到模糊
  • 空间复杂度:O(1) - 极致优化,没有多余内存占用

黄金程序员的优雅:通过二分查找,我们把两个数组的问题转化为单一数组的查找问题,就像把复杂的爱情问题简化为"你喜欢我还是她"的选择题

提交结果
在这里插入图片描述

王者进阶:实战中的性能优化与扩展

内存优化:预分配数组容量,避免动态扩容

// 预分配足够容量,避免动态扩容
func findMedianSortedArraysOptimized(nums1 []int, nums2 []int) float64 {// ... 与黄金解法相同的核心逻辑 ...// 性能优化点:预先计算可能用到的变量totalLength := m + nisOdd := totalLength % 2 == 1// ...
}

并发安全版:在Go并发场景中使用互斥锁

import "sync"var mu sync.Mutexfunc findMedianSortedArraysConcurrent(nums1 []int, nums2 []int) float64 {mu.Lock()defer mu.Unlock()return findMedianSortedArrays(nums1, nums2)
}

算法迁移:二分思想的「七十二变」

二分查找就像算法世界的「瑞士军刀」,除了找中位数,还能解决:

  1. 寻找两个数组的第k小元素:把中位数问题推广到任意k值
  2. 分割数组的最大值最小化:像切披萨一样公平分配
  3. 在旋转排序数组中查找目标:旋转数组中的"寻宝游戏"

结语:算法优化的本质是「精准打击」

从青铜的O(m+n)到王者的O(log(min(m,n))),我们见证了算法优化的「进化史」。就像从步行到高铁的交通革命,每一次优化都是对「 unnecessary work 」的无情删减。

面试金句:当面试官问你如何优化两个数组的中位数查找时,你可以自信地说:“我用二分查找实现O(log(min(m,n)))复杂度,比题目要求的O(log(m+n))还快——就像兔子中的博尔特,不仅赢了比赛,还打破了世界纪录!”

算个球的算法哲学:算法优化的精髓,在于找到问题的「阿喀琉斯之踵」——有时候少即是多,简单即是美。

欢迎大家点赞,收藏,评论,转发,你们的支持是我最大的写作动力

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/86423.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/86423.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/86423.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用tensorflow的线性回归的例子(一)

拟合y2x1 import matplotlib.pyplot as plt import numpy as np import tensorflow as tf print(tf.__version__) %matplotlib inline #载入随机种子 np.random.seed(5) #生成100个等差序列&#xff0c;每个值在-1 - 1 之间 x_data np.linspace(-1,1,100) #y 2x …

OpenLayers 渲染之矢量影像图层

前言 :::block-1 对于像GeoJSON、KML等地理数据格式的文件&#xff0c;最常用的方法都是通过VectorLayer进行渲染。除此之外&#xff0c;还可以使用VectorImage&#xff08;矢量影像图层&#xff09;进行渲染。本文主要介绍在客户端拖动上传GeoJSON、KML等文件&#xff0c;并采…

Feign 实战指南:从 REST 替代到性能优化与最佳实践

Feign 实战指南&#xff1a;从 REST 替代到性能优化与最佳实践 一 . Feign 替代 RestTemplate1.1 RestTemplate 方式调用存在的问题1.2 Feign 的介绍1.3 定义和使用 Feign 客户端1.3.1 引入依赖1.3.2 添加注解1.3.3 编写 Feign 的客户端进行接口声明1.3.4 测试小结 1.4 通过 PO…

什么是国际期货?期货交易平台搭建

国际期货&#xff08;International Futures&#xff09;&#xff0c;又称外盘期货或全球期货&#xff0c;是指在中国大陆以外的交易所进行标准化合约交易的金融衍生品市场。其核心特征、功能及与国内期货的区别如下&#xff1a; &#x1f4cd; 一、定义与核心特征 全球化交易…

考取华为HCIE-AI有什么用?

在人工智能技术重塑各行各业的浪潮中&#xff0c;掌握核心AI能力成为专业人士的制胜关键。华为推出的HCIE-AI Solution Architect&#xff08;华为认证ICT专家-AI解决方案架构师&#xff09;&#xff0c;正是面向这一领域顶尖人才设立的最高级别认证。主要是为了培养和认证掌握…

Maven 使用说明和配置

作者&#xff1a;小凯 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 一、前言 Apache Maven (opens new window)是一个软件项目管理、构建和依赖工具。基于项目对象模型 (POM) 的概念&#xff0c;Maven 可以通过中央信息来管理项目的构建、…

【Docker管理工具】安装Docker容器自动更新工具Watchtower

【Docker管理工具】安装Docker容器自动更新工具Watchtower 一、Watchtower介绍1.1 Watchtower简介1.2 Watchtower使用注意1.3 Watchtower使用场景1.4 Docker容器介绍 二、本次实践介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版…

AI优化SEO关键词精进

内容概要 随着人工智能技术的飞速发展&#xff0c;其在搜索引擎优化&#xff08;SEO&#xff09;领域的应用正引发深刻变革。本文将系统探讨AI如何革新传统的关键词优化策略&#xff0c;通过更智能的分析与匹配方法&#xff0c;显著提升内容在搜索结果中的可见度与排名。核心议…

canvas面试题200道

下面是一份 200 条关于 HTML5 Canvas 的面试题合集,适用于前端开发岗位的中高级工程师面试准备。内容涵盖基础概念、绘图操作、性能优化、动画实现、安全机制等多个方面,并附有参考答案或解析建议。 🧠 一、Canvas 基础知识(1-40) 1. 什么是 HTML5 Canvas? <canvas&…

Java 大视界 -- Java 大数据在智能安防视频监控系统中的目标轨迹预测与防范策略制定(325)

Java 大视界 -- Java 大数据在智能安防视频监控系统中的目标轨迹预测与防范策略制定&#xff08;325&#xff09; 引言&#xff1a;正文&#xff1a;一、Java 驱动的安防视频数据采集与预处理架构1.1 多路异构视频流合规接入层&#xff08;GB/T 28181-2021 全协议适配&#xff…

【Python】实现对LGBT+ rights worldwide (2025)数据集的可视化展示

我用夸克网盘分享了「lgbtq_rights_by_country数据集」&#xff0c;点击链接即可保存。 链接&#xff1a;https://pan.quark.cn/s/aa0fa91491e8 摘要&#xff1a; 本文运用Python编程实现对LGBTQ权利相关数据的处理与可视化展示。通过直方图与地图两种可视化方式&#xff0c;分…

车载通信架构 --- ECU刷写与busoff原则

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

【windows处理技巧】如何缩小PDF

原因&#xff1a;近日输出的PDF太大&#xff0c;渲染需要较多的时间&#xff0c;所以需要缩小一下PDF。 操作工具&#xff1a;adobe acrobat pro 方法&#xff1a;导入--另存为--缩减 初始&#xff1a; 压缩后

OpenCV图像添加水印

一、前言 在数字图像处理中&#xff0c;为图片添加水印是一项常见且重要的技术。无论是版权保护、品牌宣传还是防止未经授权的使用&#xff0c;水印都能发挥重要作用。OpenCV作为一款强大的计算机视觉库&#xff0c;提供了丰富的功能来实现各种水印效果。本教程将详细介绍如何…

OpenCV CUDA模块设备层-----双曲正弦函数sinh()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 OpenCV的CUDA 模块&#xff08;cv::cudev&#xff09;中的一个设备端数学函数&#xff0c;用于在 GPU 上对 uchar3 类型的像素值&#xff08;如R…

使用 Xinference 命令行工具(xinference launch)部署 Nanonets-OCR-s

使用Xinference命令行工具(xinference launch)部署Nanonets-OCR-s 一、核心优势与适用场景 通过xinference launch命令可直接在命令行完成模型部署,无需编写Python代码,适合快速验证或生产环境批量部署。 二、部署步骤:从命令行启动模型 1. 确认环境与依赖 已安装Xinf…

鸿蒙 List 组件解析:从基础列表到高性能界面开发指南

一、引言&#xff1a;列表布局 —— 鸿蒙应用的数据展示中枢 在鸿蒙应用开发体系中&#xff0c;列表布局是处理结构化数据展示的核心场景。从新闻资讯的信息流、电商平台的商品陈列到任务管理的待办事项&#xff0c;几乎所有中大型应用都依赖高效的列表组件实现数据可视化。鸿…

原生微信小程序中限制多选框(Checkbox)可选个数的实现详解

在实际业务场景中&#xff0c;我们经常会遇到表单中的复选框多选限制需求。例如最多只能选择 3 个爱好、标签、兴趣点等&#xff0c;这时就需要在微信小程序中手动控制 Checkbox 的选择行为。 本文将通过一个完整的示例&#xff0c;演示如何实现最多只能选择 N 个的 Checkbox …

OpenCV CUDA模块设备层-----线性插值函数log()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数用于创建线性插值访问器&#xff0c;支持对GPU内存中的图像数据进行双线性插值采样。主要应用于图像缩放、旋转等几何变换中需要亚像素级精…

Redis 单线程的“天花板”与集群的必要性

虽然 Redis 以其单线程模型&#xff08;主要是处理请求的核心逻辑&#xff09;带来了极高的性能和简洁性&#xff0c;但这并不意味着它没有瓶颈。 CPU 瓶颈&#xff1a;当业务逻辑复杂&#xff0c;或者 Redis 执行大量计算密集型操作&#xff08;比如使用 Lua 脚本进行复杂处理…