当前位置: 首页 > article >正文

别再死记硬背排序了!‘原地哈希’如何用交换搞定特定数组排序(保姆级图解)

别再死记硬背排序了‘原地哈希’如何用交换搞定特定数组排序保姆级图解每次提到排序算法你的第一反应是不是快速排序、归并排序这些经典方法但面对特定场景的数组排序这些大炮打蚊子式的通用解法往往效率不足。本文将带你用原地哈希这一精巧思路解决数值范围在[1,n]且不重复的数组排序问题——无需额外空间时间复杂度O(n)比传统排序快一个数量级1. 为什么通用排序算法不是最优解假设我们有一个数组[3,1,2,5,4]数值范围恰好是1到5且不重复。用快速排序需要O(nlogn)时间还要消耗递归栈空间。但仔细观察会发现每个元素的值就是它最终应该在的索引位置即数字3应该放在索引3的位置注意这里我们假设数组从1开始计数。这种现象背后隐藏着一个关键特性数组元素本身就是完美的哈希键无需比较通过值到索引的直接映射即可确定位置提示当数据满足值即索引特性时排序问题就转化为将每个元素放到它值对应的位置2. 原地哈希的核心思想原地哈希的精妙之处在于利用数组自身空间完成排序整个过程就像玩一场数字归位游戏初始化从第一个元素开始遍历位置检查如果当前元素不在它值对应的位置上即arr[i] ! i交换操作将该元素与它正确位置上的元素交换重复处理对新交换来的元素重复上述过程让我们用实际例子演示这个过程。考虑数组[3,1,2,5,4]的排序步骤操作步骤数组状态说明初始状态[3,1,2,5,4]数字3不在索引3的位置交换3-2[2,1,3,5,4]把3放到索引3换来2交换2-1[1,2,3,5,4]把2放到索引2换来1检查1[1,2,3,5,4]1已在正确位置检查4[1,2,3,5,4]数字5不在索引5的位置交换5-4[1,2,3,4,5]把5放到索引5换来4检查4[1,2,3,4,5]4已在正确位置3. 置换环理解算法的关键模式上述交换过程实际上是在处理置换环——这是原地哈希最精妙的部分。每个环代表一组需要循环交换的元素环的发现从一个元素出发按照它的值作为索引不断追踪直到回到起点环的处理通过n-1次交换可以将环内所有元素归位以数组[4,3,2,1]为例第一个环4→1→4交换4和1第二个环3→2→3交换3和2def cyclic_sort(nums): i 0 while i len(nums): correct_pos nums[i] - 1 # 计算正确位置假设数组从1开始 if nums[i] ! nums[correct_pos]: nums[i], nums[correct_pos] nums[correct_pos], nums[i] else: i 1 return nums注意Python实现中要处理从0开始索引的情况因此需要nums[i] - 14. 复杂度分析与适用场景与通用排序算法对比算法时间复杂度空间复杂度适用条件快速排序O(nlogn)O(logn)通用场景归并排序O(nlogn)O(n)需要稳定排序原地哈希O(n)O(1)值在[1,n]且不重复的数组适用场景判断标准数组元素是连续的整数或有明确的范围映射元素不重复或允许覆盖知道元素与索引的明确对应关系典型应用案例连续编号的用户ID排序数据库自增主键的重排特定条件下的索引优化5. 边界情况与常见错误即使理解了核心思想实现时仍会遇到这些坑索引偏移问题语言差异C/Python等从0开始某些场景从1开始解决方案明确文档约定必要时做±1调整重复元素处理# 错误示例遇到重复元素会死循环 nums [1,1,2] # 正确做法先检查是否满足不重复条件越界访问当元素值超出数组范围时需特别处理防御性编程检查if nums[i] len(nums) or nums[i] 1: raise ValueError(元素值超出有效范围)6. 算法可视化一步步看交换过程让我们用图形化方式展示[4,3,2,1]的排序过程初始状态 索引: [0,1,2,3] 值: [4,3,2,1] 步骤1处理索引0值4 4应该在索引3 → 交换0和3 [1,3,2,4] 步骤2新来的1应该在索引0 → 已正确 移动指针到索引1 步骤3处理索引1值3 3应该在索引2 → 交换1和2 [1,2,3,4]这种可视化方法特别适合教学演示建议读者在纸上自己演练几个例子。7. 与其他特殊排序的对比当数据具有特殊属性时还有这些高效排序方法计数排序需要O(nk)空间k为数值范围桶排序需要数据均匀分布基数排序适合固定位数的数字相比之下原地哈希的优势在于真正的原地操作连计数数组都不需要交换次数最少每个元素最多两次交换代码实现极其简洁8. 实际工程中的应用技巧在真实项目中应用原地哈希时这些技巧能帮你避免翻车前置校验def is_eligible_for_cyclic_sort(nums): return max(nums) - min(nums) len(nums) - 1性能优化对于部分有序的数组可以记录交换次数提前退出使用并行处理独立置换环需要无环间依赖调试建议打印每次交换后的数组状态使用断言检查不变式assert len(set(nums)) len(nums), 存在重复元素9. 从算法设计中学到的思维方式原地哈希给我们展示了算法设计的几个重要原则利用数据特性发现值即索引这一隐藏关系空间效率优先在移动设备等内存受限场景特别有价值问题转化思维将排序问题转化为元素归位问题这种思维方式可以推广到其他场景。比如处理[0,n-1]范围的数组时只需调整索引映射关系# 对于0-based的[0,n-1]数组 correct_pos nums[i] # 不需要-1调整10. 扩展练习与挑战题目为了巩固理解尝试解决这些变种问题找出[1,n]数组中缺失的数字LeetCode 268找出所有重复的数字LeetCode 442恢复被打乱的[1,n]数组需要记录原始位置处理允许包含[1,n]范围外特殊值的数组对于进阶学习者可以思考如何修改算法处理包含负数的数组如果有多个重复元素如何调整策略能否用同样思路处理非数值型数据

相关文章:

别再死记硬背排序了!‘原地哈希’如何用交换搞定特定数组排序(保姆级图解)

别再死记硬背排序了!‘原地哈希’如何用交换搞定特定数组排序(保姆级图解) 每次提到排序算法,你的第一反应是不是快速排序、归并排序这些经典方法?但面对特定场景的数组排序,这些"大炮打蚊子"式的…...

PSIM 9.0 手把手教学:从零搭建直流电机双闭环调速模型(附完整代码与波形分析)

PSIM 9.0 手把手教学:从零搭建直流电机双闭环调速模型(附完整代码与波形分析) 在电力电子与电机控制领域,仿真技术已成为工程师和研究人员不可或缺的工具。PSIM作为一款专业的电力电子仿真软件,以其高效的仿真速度和直…...

学妹问降AI率工具选哪个性价比最高?4款降AI软件1万字花多少过AIGC检测

学妹问降AI率工具选哪个性价比最高?4款降AI软件1万字花多少过AIGC检测 学妹的具体问题 3 月 23 号晚上学妹问我:「学姐我送知网测了 AI 率 65%——市面降 AI 工具一堆我怎么选性价比最高的?预算 300 元以内」。 「性价比最高」是用户最常问…...

PTA数据结构实战:层次遍历巧解二叉树叶结点输出

1. 从问题理解到解题思路 第一次看到PTA上这道二叉树题目时,我也被题目描述唬住了。题目要求按从上到下、从左到右的顺序输出所有叶结点,这不就是典型的层次遍历(BFS)应用场景吗?但仔细分析输入格式后,我发…...

从自动化到智能代理:构建家庭智能中枢的架构与实践

1. 项目概述与核心价值最近在折腾智能家居和自动化流程,发现市面上的很多方案要么太“重”,需要依赖特定品牌的生态闭环;要么太“散”,各种工具和脚本堆在一起,管理起来一团乱麻。直到我遇到了一个名为“Home-agent-as…...

ESP32-C3驱动2寸ST7789屏幕?手把手教你搞定LVGL移植(附避坑代码)

ESP32-C3与ST7789屏幕的LVGL移植实战指南 在物联网设备开发中,显示交互界面往往是提升用户体验的关键一环。ESP32-C3作为乐鑫推出的高性价比RISC-V芯片,搭配ST7789驱动的2寸LCD屏幕,能够构建出性能稳定、成本可控的嵌入式显示方案。本文将带你…...

AI Agent Harness多模型融合管控

AI Agent Harness实战:从0到1搭建企业级多模型融合管控系统 副标题:兼容OpenAI/Claude/Llama3/通义千问,解决多模型调度、能力互补、成本管控、一致性校验核心痛点 摘要/引言 大家好,我是专注大模型应用落地的资深架构师老周,最近半年帮3家不同行业的企业落地了多模型Ag…...

Cursor编辑器自动化实践:利用Sisyphus脚本解放重复开发任务

1. 项目概述与核心价值最近在GitHub上看到一个挺有意思的项目,叫Fguedes90/cursor-sisyphus。乍一看这个标题,可能会有点摸不着头脑,但如果你是一个深度使用Cursor AI代码编辑器的开发者,或者对AI辅助编程的自动化流程感兴趣&…...

音乐解锁实战:如何让网易云音乐的加密文件在任意设备自由播放

音乐解锁实战:如何让网易云音乐的加密文件在任意设备自由播放 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾经在网易云音乐下载了心爱的歌曲,却发现只能在特定客户端播放,无法在车载音响…...

ParsecVDisplay终极指南:解锁Windows虚拟显示器完整解析

ParsecVDisplay终极指南:解锁Windows虚拟显示器完整解析 【免费下载链接】parsec-vdd ✨ Perfect virtual display for game streaming 项目地址: https://gitcode.com/gh_mirrors/pa/parsec-vdd 你是否曾渴望拥有额外的屏幕空间,却受限于物理显示…...

Neovim AI编程助手codecompanion.nvim:无缝集成与高效开发实践

1. 项目概述:一个为Neovim而生的AI编程伴侣如果你和我一样,是个深度依赖Neovim进行日常开发的程序员,那么你一定经历过这样的时刻:面对一段复杂的逻辑,需要反复查阅文档;或者写一个函数时,卡在某…...

3分钟掌握网页视频下载:Chrome扩展VideoDownloadHelper完全指南

3分钟掌握网页视频下载:Chrome扩展VideoDownloadHelper完全指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 你是否曾经遇到想…...

别再手动改路由了!用Ant Design Vue的Menu组件动态生成“顶一左多”级导航菜单

基于Ant Design Vue的声明式导航菜单架构设计 在复杂后台管理系统开发中,导航菜单的动态生成与权限控制一直是架构设计的难点。传统方案往往需要在多个组件中硬编码菜单结构,导致维护成本高、权限同步困难。本文将介绍如何利用Ant Design Vue的Menu组件与…...

Git多用户代理架构解析:实现细粒度权限管理与统一访问入口

1. 项目概述:从单兵作战到团队协作的代码管理跃迁如果你是一个独立开发者,或者在一个小团队里,你可能习惯了把代码往GitHub、Gitee这样的平台上一扔,设置个私有仓库,然后通过个人账号的SSH密钥来管理访问权限。这种方式…...

基于RP2040与NeoPixel的交互式LED气泡桌:硬件选型、电路设计与动画编程全解析

1. 项目概述:打造一个会呼吸的光影气泡桌 几年前,我在一个艺术展上看到一个用灯光和烟雾营造氛围的装置,当时就被那种动态光影与物理形态结合的美感深深吸引。作为一个喜欢动手的嵌入式开发者,我一直在想,能不能做一个…...

告别点灯:用GC9A01圆形屏为你的Arduino/ESP32项目做个酷炫UI(附完整代码)

告别点灯:用GC9A01圆形屏为你的Arduino/ESP32项目做个酷炫UI(附完整代码) 在智能硬件项目中,一个精致的用户界面往往能大幅提升产品质感。GC9A01这款1.28英寸圆形TFT屏幕,以其240x240的高分辨率和IPS面板的广视角特性…...

3个技巧让LaTeX参考文献自动符合GB/T 7714国标:告别手动排版烦恼

3个技巧让LaTeX参考文献自动符合GB/T 7714国标:告别手动排版烦恼 【免费下载链接】gbt7714-bibtex-style BibTeX styles for Chinese National Standard GB/T 7714 项目地址: https://gitcode.com/gh_mirrors/gb/gbt7714-bibtex-style 还在为毕业论文、学术论…...

ARM GIC中断控制器架构与寄存器编程详解

1. ARM GIC中断控制器架构概述 中断控制器是现代处理器系统中至关重要的组件,它负责协调和管理来自各种外设的中断请求。ARM架构的通用中断控制器(GIC)经过多代演进,目前GICv3/GICv4已成为主流实现。GIC的核心功能包括中断优先级管理、中断分发、虚拟化支…...

ARM Cortex-A9 MPCore多核处理器架构与优化实践

1. ARM Cortex-A9 MPCore硬件架构概述ARM Cortex-A9 MPCore是一款广泛应用于嵌入式系统的高性能多核处理器。作为ARMv7-A架构的代表性产品,它在工业控制、汽车电子和消费电子等领域有着广泛应用。这款处理器最显著的特点是支持1-4个核心的对称多处理(SMP)配置&#…...

Windows 10系统瘦身实战:用Win10BloatRemover打造高效纯净系统

Windows 10系统瘦身实战:用Win10BloatRemover打造高效纯净系统 【免费下载链接】Win10BloatRemover Configurable CLI tool to easily and aggressively debloat and tweak Windows 10 by removing preinstalled UWP apps, services and more. Originally based on …...

树与二叉树:数据结构核心解析

引言在前面的文章中,我们已经系统学习了线性数据结构——链表、栈、队列。线性结构的特点是元素之间存在一对一的先后关系。然而,现实世界中的很多数据关系是一对多的:文件系统中的目录与子目录、公司的组织架构、网页的 DOM 结构……树&…...

告别‘鬼影’与模糊:深入解读RangeNet++如何用高效kNN后处理搞定LiDAR语义分割的边界难题

RangeNet:用GPU加速的kNN后处理破解LiDAR语义分割的边界模糊难题 当自动驾驶车辆以每小时60公里的速度行驶时,每100毫秒的决策延迟意味着1.67米的盲区——这恰好是许多交通事故发生的临界距离。在LiDAR语义分割领域,传统方法在点云投影与反投…...

基于LLM智能体编排框架call-agents-help的实战指南

1. 项目概述与核心价值最近在GitHub上看到一个挺有意思的项目,叫heyuqiu2023/call-agents-help。光看名字,你可能会有点摸不着头脑,这“呼叫代理助手”到底是个啥?其实,这是一个围绕大语言模型(LLM&#xf…...

星露谷物语SMAPI终极指南:5分钟解锁无限模组世界

星露谷物语SMAPI终极指南:5分钟解锁无限模组世界 【免费下载链接】SMAPI The modding API for Stardew Valley. 项目地址: https://gitcode.com/gh_mirrors/smap/SMAPI 你是否曾梦想过让星露谷物语变得更加精彩?想象一下:当你辛苦耕种…...

Transformer架构与混合专家系统(MoE)的技术演进与应用

1. Transformer架构与混合专家系统(MoE)的演进之路2017年,Transformer架构的横空出世彻底改变了自然语言处理的游戏规则。这种基于自注意力机制的架构不仅在各种序列建模任务中展现出惊人性能,更为后续的大规模语言模型奠定了坚实基础。然而,…...

终极指南:如何用Reset-Windows-Update-Tool快速修复Windows更新故障

终极指南:如何用Reset-Windows-Update-Tool快速修复Windows更新故障 【免费下载链接】Reset-Windows-Update-Tool Troubleshooting Tool with Windows Updates (Developed in Dev-C). 项目地址: https://gitcode.com/gh_mirrors/re/Reset-Windows-Update-Tool …...

从入门到精通:trtexec命令行工具在TensorRT模型部署中的实战指南

1. trtexec工具基础入门 第一次接触trtexec时,我也被这个命令行工具的参数数量吓到了。但实际用下来发现,它就像瑞士军刀一样,虽然功能多但每个都很实用。trtexec是TensorRT安装包自带的命令行工具,主要用来做三件事:…...

.NET逆向工程新选择:dnSpyEx调试器与程序集编辑全解析

.NET逆向工程新选择:dnSpyEx调试器与程序集编辑全解析 【免费下载链接】dnSpy Unofficial revival of the well known .NET debugger and assembly editor, dnSpy 项目地址: https://gitcode.com/gh_mirrors/dns/dnSpy 你是否曾面对一个没有源代码的.NET程序…...

终极指南:Diablo Edit2暗黑破坏神2存档修改器完整使用教程

终极指南:Diablo Edit2暗黑破坏神2存档修改器完整使用教程 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit 你是否曾为暗黑破坏神2中重复刷装备而烦恼?是否因为技能点分配失…...

code2prompt:AI编程助手的高效代码上下文生成工具详解

1. 项目概述:从代码到提示词的“翻译官”最近在折腾一些AI辅助编程或者代码分析的工具时,我经常遇到一个头疼的问题:如何把我手头的一大段项目代码,高效、准确地“喂”给像ChatGPT、Claude或者GitHub Copilot这样的AI助手&#xf…...