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

LeetCode 2418:按身高排序 —— 题解

👋 欢迎阅读

🎯 欢迎来到「按身高排序」题解之旅!本文将带你从“按身高降序输出名字”这一排序需求出发,深入理解多种排序实现方式,并掌握创建二元组、哈希表映射、对下标排序三种经典技巧的适用场景。

在开始之前,建议你先:

  • 了解题目背景:这是 LeetCode 2418 题,给定两个等长数组namesheights(身高值互不相同),要求按身高降序返回对应的名字数组。这是一道排序与映射的入门题,但提供了多种解法思路,可灵活应用到其他类似场景。

  • 明确学习目标:掌握三种实现方式——
    创建二元组:将(身高, 名字)组合后排序,直接提取名字;
    哈希表映射:用哈希表存储<身高 -> 名字>,对身高数组排序后查表;
    对下标排序(常用技巧):对下标数组[0, n-1]heights降序排序,再按排好的下标取names
    理解每种方法的优劣和适用性,尤其是下标排序在避免额外空间或保持原数据不变时的通用价值。

本文将从问题转化、三种解法详解(二元组/哈希/下标排序)、代码实现到复杂度分析,层层递进。即使你对排序和映射还不熟悉,我们也会从“把身高和名字绑在一起”的直觉出发,让你轻松抓住核心思想——排序的本质是比较,但比较的对象可以是组合、映射关系或索引。现在,让我们一起按身高排好队,叫出对应名字吧! 📏📛


一、题目

2418. 按身高排序 - 力扣(LeetCode)

二、做题思路

1. 问题分析(前置分析)

给定两个长度相等的数组:names(名字)和heights(身高,互不相同),要求按身高降序返回对应的名字数组。
核心挑战是:在排序时保持名字与身高的对应关系
有三种常用解法:创建二元组哈希表映射对下标排序


2. 解法一:创建二元组

2.1 核心思路

  • 将每个人封装为一个二元组(身高, 名字),存入新数组。

  • 对二元组数组按身高降序排序

  • 依次提取排序后的名字,组成结果数组。

2.2 正确性说明(简单版本)

二元组将每个名字与其身高绑定在一起,排序时整体移动,不会出现错位。只要按身高降序排序,提取出的名字顺序即为题目所求。

2.3 实现细节(边界防护)

  • 使用vector<pair<int, string>> people存储二元组。

  • 自定义排序:按first(身高)降序,若身高相同则按原顺序(但题目保证身高互不相同)。

  • 遍历排序后的二元组,取出second加入结果数组。

2.4 代码

class Solution { public: vector<string> sortPeople(vector<string>& names, vector<int>& heights) { int n = names.size(); // 1. 创建二元组数组 vector<pair<int, string>> people; for (int i = 0; i < n; i++) { people.push_back({heights[i], names[i]}); } // 2. 按身高降序排序 sort(people.begin(), people.end(), [](const pair&lt;int, string&gt;&amp; a, const pair&lt;int, string&gt;&amp; b) { return a.first &gt; b.first; // 降序 }); // 3. 提取名字 vector&lt;string&gt; ans; for (auto&amp; p : people) { ans.push_back(p.second); } return ans; } };

2.5 流程图


3. 解法二:哈希表映射

3.1 核心思路

  • 建立哈希表unordered_map<int, string>,将heights[i]映射到names[i]

  • heights数组降序排序

  • 遍历排序后的heights,用每个身高值去哈希表中查找对应的名字,依次加入结果。

3.2 正确性说明(简单版本)

因为身高值互不相同,哈希表的键唯一,所以每个身高能精确映射到唯一名字。按身高降序查找,得到的名字顺序即为目标顺序。

3.3 实现细节(边界防护)

  • 使用unordered_map<int, string> hash存储映射。

  • heights数组进行降序排序(可用sort+ 自定义比较或greater<int>())。

  • 遍历排序后的heights,通过hash[height]获取对应名字。

  • 注意:哈希表查找是 O(1),整体时间复杂度 O(n log n),主要来自排序。

3.4 代码

class Solution { public: vector<string> sortPeople(vector<string>& names, vector<int>& heights) { int n = names.size(); // 1. 建立哈希映射 unordered_map<int, string> hash; for (int i = 0; i < n; i++) { hash[heights[i]] = names[i]; } // 2. 复制身高数组并降序排序 vector&lt;int&gt; sortedHeights = heights; sort(sortedHeights.begin(), sortedHeights.end(), greater&lt;int&gt;()); // 3. 根据排序后的身高查找名字 vector&lt;string&gt; ans; for (int h : sortedHeights) { ans.push_back(hash[h]); } return ans; } };

3.5 流程图


4. 解法三:对下标排序(非常常用的技巧)

4.1 核心思路

  • 创建一个下标数组index,初始为[0, 1, 2, ..., n-1]

  • 不移动namesheights,而是对index进行排序,排序依据是heights[index[i]]降序。

  • 排序后,index中的顺序即为按身高降序排列的人员索引顺序。

  • 根据index顺序,从names中取出对应名字,组成结果数组。

4.2 正确性说明(简单版本)

通过下标作为“中介”,将排序逻辑从数据本身剥离index排序后记录了所有下标按身高降序的排列,再通过下标访问原数组,既能得到正确顺序,又避免了原数据的移动,是一种高效且常用的技巧。

4.3 实现细节(边界防护)

  • 初始化index[i] = i

  • 使用sort(index.begin(), index.end(), [&](int a, int b){ return heights[a] > heights[b]; })

  • 排序后,遍历index,用names[index[i]]构造结果。

  • 此方法不需要额外存储二元组或哈希表,空间复杂度 O(n)。

4.4 代码

class Solution { public: vector<string> sortPeople(vector<string>& names, vector<int>& heights) { int n = heights.size(); // 1. 创建索引数组,初始按 0..n-1 排列,用于间接排序 vector&lt;int&gt; index(n); for (int i = 0; i &lt; n; i++) { index[i] = i; } // 2. 根据身高数组对索引进行降序排序 // 自定义比较函数:索引 i 对应的人的身高如果大于索引 j 的,则 i 排在前面 sort(index.begin(), index.end(), [&amp;](int i, int j) { return heights[i] &gt; heights[j]; // 降序(从高到矮) }); // 3. 按照排序后的索引顺序,将对应的名字依次加入结果数组 vector&lt;string&gt; ret; for (auto idx : index) { ret.push_back(names[idx]); } // 4. 返回按身高降序排列的名字列表 return ret; } };

4.5 流程图


5. 三种解法对比总结

解法核心操作空间复杂度是否修改原数组
二元组创建新对象排序O(n)
哈希表键值映射 + 排序O(n)是(对 heights 排序)
下标排序排序索引数组O(n)否(不移动原数组)

🎯 闭幕

🎉 恭喜你完成了「按身高排序」问题的学习!

为了巩固知识并进一步拓展,建议你:

🚀动手实践
在 LeetCode 上提交代码,尝试不同的测试用例。

💡深入思考

  • 题目给出了三种解法:创建二元组、使用哈希表、对下标排序。这三种方法的核心思想分别是什么?各自适用于什么场景?

  • 解法三“对下标排序”是非常常用的技巧,它为什么能避免移动原始数据?如果要求最终输出名字数组,而不是下标,这种方法的优势体现在哪里?

  • 如果不仅要返回名字,还要同时返回排序后的身高,上述哪种方法最容易扩展?

📚延伸挑战

  • 将题目改为按名字的字典序排序,但需要同时输出对应的身高,你会选择哪种解法?如果名字有重复,哪种方法更稳妥?

如果你觉得本文对你有所帮助,欢迎:

👍 点赞 / 收藏
👤 关注作者,获取更多题解
💬 留言交流你的疑问或优化思路

祝你在算法之路上越走越稳,早日攻克每一道难题!下次见 🚀✨

http://www.jsqmd.com/news/1272632/

相关文章:

  • 【非标自动化】2、认识元器件(压力传感器)
  • 开源HTML编辑器选型与集成实战:从CKEditor到TinyMCE的完整指南
  • AI配音软件避坑攻略,价格透明口碑实力对比 - 工业品牌热点
  • C++线程安全队列(SafeQueue)设计与实现:生产者-消费者模型实战
  • AI伦理架构:构建负责任的算法决策系统
  • 韶关市防水补漏_2026广东西北部粤北山区漏水维修攻略与五大正规团队推荐 - 雨婺虹房屋维修
  • 果洛精选口碑瓷砖空鼓维修公司推荐(2026)厨房瓷砖脱落处理 - 北京优选
  • JavaWeb服务器与客户端交互机制及优化实践
  • 你每天看到什么、听到什么、吃什么、想什么、做什么、和谁连接,都会进入你的系统,慢慢塑造你的状态。
  • ThreadX的命名规范与编码风格
  • 上下文感知计算:核心算法与应用实践
  • 8款AI工具提升论文写作效率全攻略
  • 悟空脉爆:专注家装行业的同城IP全链路获客运营服务商 - 装企精灵GEO
  • Unity 2D动态光影系统:从原理到实战的完整指南
  • 名片识别技术:OCR原理与API开发实践
  • 北京房屋漏水维修修护攻略(2026 新版):卫生间、厨房、阳台昼夜均可上门查漏补漏 - 北京金修达天津维修部
  • 二叉排序树(BST)Java 完整实现 + 删除思路详解
  • 2026年校招「三无」应届生面试突围指南:AI能力证据链搭建法+4款工具实测,零竞赛零实习也能让面试官眼前一亮
  • 车间降温施工厂家靠谱实测排名,避坑省钱不交智商税 - 工业品牌热点
  • 快手截屏多次连续失败已经解决
  • C++实现基数排序:从原理到工程优化的完整指南
  • 智能体设计模式:人机协同、RAG与A2A通信解析
  • 终极免费指南:如何通过AO3镜像站轻松访问全球最大同人创作平台
  • Unity游戏翻译神器:XUnity.AutoTranslator完全指南 - 一键实现游戏汉化
  • Three.js实现高效水体渲染:动态波浪与光线交互
  • AI Agent 的网络出向网关:OneCLI 凭证代换实测与 6 类边界
  • 如何在英雄联盟中免费解锁全皮肤:LeagueSkinChanger完整使用教程
  • 渗透测试之信息收集全攻略:从子域名挖掘到端口扫描实战指南
  • 鲁棒优化在绿证-碳联合交易系统中的应用与实践
  • 2026年最新教程:怎么截取视频一段做成GIF 亲测好用的免费方法 - 图片处理研究员