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

面试必看:优势洗牌

贪心+双指针求解优势洗牌问题(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. 保留原数组索引是解题关键,确保排列结果能对应到题目要求的原始位置。
http://www.jsqmd.com/news/349422/

相关文章:

  • 靠Ollama做AI智能体,他月入23万,拒绝大厂offer,还被连锁企业高价收购
  • java+vue基于springboot网球馆管理系统 场地预约活动报名系统_ws1sdg96-Pycharm vue django项目源码
  • 实现Creo软件总体拥有成本降低30%实践案例
  • 尝试再次交叉编译ffmpeg
  • 树莓派WiFi设置教程,解决连不上网络问题
  • 西门子 200SMART 与显控触摸屏在 30 吨双级反渗透加 EDI 水处理系统的应用
  • 任务识别回收技术:基于任务识别的GT-SUITE闲置许可证回收
  • AI大模型教程从零基础入门到精通!一文讲清,看这一篇就够了!
  • Ollama躺赚实测:零门槛批量做电子书,每月稳入2.9万?真相藏不住了
  • 线束设计高峰期EB-Cable许可证峰值管理技巧
  • 北爪宏幸Z高达设计解析与特点,独特版模型值得收藏
  • 如何确认伪距观测方程各系数的正负
  • 2026年度抽屉拉篮深度测评与推荐,五款优选,助你厨房收纳力MAX
  • getsockopt函数用法:Windows网络编程查询socket设置教程
  • AbMole小讲堂丨Daraxonrasib(RMC-6236):新型RAS抑制剂的作用机理及研究进展
  • 专业精选,八大调味拉篮品牌深度测评与推荐
  • 太赫兹通信:6G时代的“超高速无线血液”
  • IBM AIX 关键漏洞CVE-2025-36250深度解析与应对指南
  • 孙鑫C语言视频教程 零基础入门自学指南
  • 为什么网络安全缺口很大,而招聘却很少?
  • CFormView最大化时控件位置错乱的解决方法
  • 学术论文写作全流程工具指南 (2026版)
  • canvas树叶画法教程:从叶脉到光影绘制技巧
  • 1行SQL调用AI Agent?用SQL玩转Agent+RAG,彻底打通企业所有系统​
  • 基于深度学习YOLOv11的传送带缺陷识别检测系统(YOLOv11+YOLO数据集+UI界面+登录注册界面+Python项目源码+模型)
  • AI智能体的五个难度等级(附完整代码实现)
  • 联想A850系统更新刷机教程,官方升级和第三方ROM操作指南
  • 基于深度学习YOLOv12的表情识别检测系统(YOLOv12+YOLO数据集+UI界面+登录注册界面+Python项目源码+模型)
  • 告别微调!斯坦福提出Agentic上下文工程
  • 小微商家 AI 开发平台「码上飞」:「打电话」即生成应用;ElevenLabs 新一轮融资估值飙升至 110 亿美元 丨日报