news 2026/5/3 18:33:41

面试必看:优势洗牌

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
面试必看:优势洗牌

贪心+双指针求解优势洗牌问题(C++ 实现)

题目描述

给定两个长度相等的数组nums1nums2,定义nums1相对于nums2的优势为满足nums1[i] > nums2[i]的索引i的数量。要求返回nums1的任意一个排列,使得该排列相对于nums2的优势最大化。

问题分析

结合题目要求和数据特征,我们可以先梳理核心约束与解题思路:

  1. 两个数组长度相同,排列后元素需按索引一一对应匹配;
  2. 目标是最大化满足nums1[i] > nums2[i]的索引数量,本质是用最优的匹配策略实现收益最大化;
  3. 直接暴力枚举所有排列会产生极高的时间复杂度,无法高效处理较大数据量,因此需要选择更优的算法方案。

结合问题特征,贪心算法+双指针是适配该场景的最优解:贪心策略用于保证每一步选择都能获取当前最优收益,双指针用于高效遍历匹配元素,整体算法可以在线性遍历结合排序的基础上完成计算。

算法思路

核心策略

采用贪心匹配原则:用nums1最小的可用大数去匹配nums2中对应元素,无法满足大小关系时,用nums1中最小的数去填充,最大化有效匹配数量的同时,减少优质元素的浪费。

具体步骤

  1. 数组预处理
    • nums1执行升序排序,方便通过双指针快速获取当前最大/最小可用元素;
    • nums2构建(值, 原索引)的键值对数组,再对该数组执行升序排序。保留原索引是为了保证最终结果能对应到题目要求的原始位置。
  2. 双指针初始化
    定义左指针left指向排序后nums1的起始位置(最小值),右指针right指向排序后nums1的末尾位置(最大值)。
  3. 逆序遍历匹配
    从大到小遍历处理后的nums2数组,依次判断当前元素:
    • nums1的当前最大值大于nums2的当前元素,将该最大值填入结果数组的对应原始索引,右指针左移;
    • 若不满足大小关系,说明当前最大元素也无法形成优势,改用nums1的当前最小值填充,左指针右移。
  4. 输出结果
    遍历完成后,结果数组即为满足条件的nums1最优排列。

C++ 实现代码

#include<vector>#include<algorithm>usingnamespacestd;classSolution{public:vector<int>advantageCount(vector<int>&nums1,vector<int>&nums2){// 获取数组长度intn=nums1.size();// 初始化结果数组,长度与输入数组一致vector<int>res(n,0);// 存储nums2的(值, 原索引)对,保留原始位置信息vector<pair<int,int>>nums2_temp;for(inti=0;i<n;++i){nums2_temp.emplace_back(nums2[i],i);}// 对nums1升序排序sort(nums1.begin(),nums1.end());// 对nums2的键值对数组按值升序排序sort(nums2_temp.begin(),nums2_temp.end());// 双指针初始化:left指向nums1最小值,right指向nums1最大值intleft=0;intright=n-1;// 逆序遍历排序后的nums2_temp,从大元素开始匹配for(inti=n-1;i>=0;--i){intval=nums2_temp[i].first;// nums2当前元素值intindex=nums2_temp[i].second;// 该元素在原数组中的索引// 贪心选择:能用大值匹配就用大值,否则用小值填充if(val<nums1[right]){res[index]=nums1[right];--right;}else{res[index]=nums1[left];++left;}}returnres;}};

复杂度分析

时间复杂度

算法主要耗时操作为排序操作:

  • nums1排序的时间复杂度为O(nlog⁡n)O(n\log n)O(nlogn)
  • nums2键值对数组排序的时间复杂度为O(nlog⁡n)O(n\log n)O(nlogn)
  • 后续双指针遍历为线性操作,时间复杂度为O(n)O(n)O(n)

整体时间复杂度为O(nlog⁡n)O(n\log n)O(nlogn),在数据量较大时仍能保持高效运行。

空间复杂度

  • 额外开辟了存储nums2键值对的数组nums2_temp和结果数组res,两者空间开销均为O(n)O(n)O(n)
  • 排序过程中递归调用栈的空间开销为O(log⁡n)O(\log n)O(logn),可忽略不计。

整体空间复杂度为O(n)O(n)O(n),属于线性空间开销。

算法验证与适用场景

该算法通过贪心策略保证了每一步匹配的最优性,双指针遍历避免了重复判断,能够稳定得到优势最大化的排列。适用于题目给定的所有常规场景,无特殊数据边界限制,在力扣对应题目中可通过全部测试用例。


总结

  1. 本题核心解法为贪心算法+双指针,通过排序预处理和逆序匹配实现最优解;
  2. 算法时间复杂度为O(nlog⁡n)O(n\log n)O(nlogn),空间复杂度为O(n)O(n)O(n),兼顾了时间效率与实现简洁性;
  3. 保留原数组索引是解题关键,确保排列结果能对应到题目要求的原始位置。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/2 13:00:25

孙鑫C语言视频教程 零基础入门自学指南

孙鑫的C语言入门视频教程在编程初学者中有着很好的口碑&#xff0c;作为从事编程教学多年的讲师&#xff0c;我观察过许多学生通过学习这套教程成功入门编程。这套教程体系完整&#xff0c;讲解细致&#xff0c;特别适合那些想要系统学习C语言基础的学习者。下面我将结合教学经…

作者头像 李华
网站建设 2026/5/1 8:48:34

太赫兹通信:6G时代的“超高速无线血液”

太赫兹通信是无线通信领域的前沿技术&#xff0c;它利用太赫兹波&#xff08;频率0.1-10 THz&#xff0c;波长0.03-3 mm&#xff09;作为信息载体&#xff0c;被认为是未来6G移动通信的核心技术之一。下面我将从技术原理、独特优势、关键挑战和应用前景等方面全面解析这一革命性…

作者头像 李华
网站建设 2026/5/1 16:18:20

为什么现在都说说运维很难?

一、公司内部维护 对SVN、git的每日备份&#xff0c;编写shell自动定期对SVN的账号进行密码更新&#xff0c;并且发送邮件通知。开发数据库和测试数据库的每日按库表备份。 使用markdown&#xff0c;建立小型的wiki&#xff0c;编写公司内部的信息文档&#xff0c;避免重复、无…

作者头像 李华
网站建设 2026/5/1 16:12:29

1行SQL调用AI Agent?用SQL玩转Agent+RAG,彻底打通企业所有系统​

你有没有遇到过这样的场景&#xff1f;凌晨两点被紧急电话吵醒&#xff0c;生产线突然停机&#xff0c;维修团队在飞书里翻找设备手册&#xff0c;客服部门在CRM里查询历史工单&#xff0c;工程师在企业微信群里疯狂所有人——而解决问题的关键文档&#xff0c;正静静地躺在某个…

作者头像 李华
网站建设 2026/5/1 18:45:12

教工平台采购避坑指南:别只看价格,服务价值更重要

✅作者简介&#xff1a;合肥自友科技 &#x1f4cc;核心产品&#xff1a;智慧校园平台(包括教工管理、学工管理、教务管理、考务管理、后勤管理、德育管理、资产管理、公寓管理、实习管理、就业管理、离校管理、科研平台、档案管理、学生平台等26个子平台) 。公司所有人员均有多…

作者头像 李华