news 2026/5/1 9:03:53

【剑斩OFFER】算法的暴力美学——翻转对

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【剑斩OFFER】算法的暴力美学——翻转对

一、题目描述

二、算法原理

思路:归并排序(降序) + 双指针

如果:nums [ cur1 ] <= 2 * nums[ cur2 ],那么证明我们还没有找到符合题目要求的 nums[ cur ] ,所以:cur2 ++

如果:nums[ cur1 ] > 2 * nums[ cur2 ] ,符合题目要求,因为 nums[ cur1 ] > 2 * nums[ cur2 ] 又因为数组都是降序的,所以 【 cur2,right 】 这个区间的数字都符合题目要求。统计完符合题目要求的数字之后,那么 cur1++ 看看后面数字是否有数字大于2倍的nums[ cur2 ] ,那我们的 cur2 还要从头开始判断 nums [ cur1 ] <= 2 * nums[ cur2 ] 吗?答案是:不用,因为 cur1 没有 ++ 之前就已经没有符合题目要求了:nums[ cur1 ] <= 2 * nums[ cur2 ](cur2:【mid + 1,cur2 - 1】),因为数组是降序的,cur1++ 之后更加不会符合题目要了;所以 cur2 不用返回数组的开头重新判断一遍,这样会增加时间复杂度的。

注意:上面的内容不能在合并数组的时候进行,在合并之前进行,因为在合并的时候进行会导致合并数组和找翻转对的过程冲突;所以我们要在合并数组之前进行,此时这两个数组都是有序的。

三、代码实现

//降序找翻转对 class Solution { int count; public: int reversePairs(vector<int>& nums) { count = 0; vector<int> tmp; tmp.resize(nums.size()); Quicksort(0,nums.size() - 1,nums,tmp); return count; } void Quicksort(int l,int r,vector<int>& nums,vector<int>& tmp) { if(l >= r) return; int keyi = (l + r) >> 1; Quicksort(l,keyi,nums,tmp);//左边:【 l , keyi 】 Quicksort(keyi + 1,r,nums,tmp);//右边:【keyi + 1,r 】 int begin1 = l,end1 = keyi;//左边数组 int begin2 = keyi + 1,end2 = r;//右边数组 int index = l;//遍历起始点 int begin3 = begin1,end3 = end1; int begin4 = begin2,end4 = end2; while(begin3 <= end3 && begin4 <= end4)//提前保存翻转对 { long long tmp_i = 2 * (long long)nums[begin4];//防止数据丢失 while(begin4 <= end4 && tmp_i >= nums[begin3]) { begin4++; tmp_i = 2 * (long long)nums[begin4]; } if(begin4 > end4) break; count += end4 - begin4 + 1; begin3++; } while(begin1 <= end1 && begin2 <= end2)//比较遍历 { if(nums[begin1] > nums[begin2]) { tmp[index++] = nums[begin1++]; } else { tmp[index++] = nums[begin2++]; } } while(begin1 <= end1) tmp[index++] = nums[begin1++];//把左边剩余的数字放到 tmp while(begin2 <= end2) tmp[index++] = nums[begin2++];//把右边剩余的数字放到 tmp for(int i = l;i < index;i++) nums[i] = tmp[i];//把 tmp 里面的数字放回到原数组 nums } };
//升序找翻转对 class Solution { int count; public: int reversePairs(vector<int>& nums) { count = 0; vector<int> tmp; tmp.resize(nums.size()); Quicksort(0,nums.size() - 1,nums,tmp); return count; } void Quicksort(int l,int r,vector<int>& nums,vector<int>& tmp) { if(l >= r) return; int keyi = (l + r) >> 1; Quicksort(l,keyi,nums,tmp);//左边:【 l , keyi 】 Quicksort(keyi + 1,r,nums,tmp);//右边:【keyi + 1,r 】 int begin1 = l,end1 = keyi;//左边数组 int begin2 = keyi + 1,end2 = r;//右边数组 int index = l;//遍历起始点 int begin3 = begin1,end3 = end1; int begin4 = begin2,end4 = end2; while(begin3 <= end3 && begin4 <= end4)//提前保存翻转对 { while(begin3 <= end3 && nums[begin3]/2.0 <= nums[begin4])//防止 5 / 2 = 2 == 2 ,所以不能/2 ,而是/2.0;5/2.0 = 2.5 > 2 { begin3++; } if(begin3 > end3) break; count += end3 - begin3 + 1; begin4++; } while(begin1 <= end1 && begin2 <= end2)//比较遍历,升序 { if(nums[begin1] > nums[begin2]) { tmp[index++] = nums[begin2++]; } else { tmp[index++] = nums[begin1++]; } } while(begin1 <= end1) tmp[index++] = nums[begin1++];//把左边剩余的数字放到 tmp while(begin2 <= end2) tmp[index++] = nums[begin2++];//把右边剩余的数字放到 tmp for(int i = l;i < index;i++) nums[i] = tmp[i];//把 tmp 里面的数字放回到原数组 nums } };
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 4:56:12

【金融级审计日志构建指南】:从Agent采集到监管报送的5步闭环方案

第一章&#xff1a;金融级审计日志的核心价值与合规要求在金融行业&#xff0c;系统操作的可追溯性与数据完整性是安全治理的基石。审计日志不仅记录关键业务操作、用户行为和系统事件&#xff0c;更是满足监管合规&#xff08;如GDPR、PCI-DSS、SOX&#xff09;的必要手段。其…

作者头像 李华
网站建设 2026/5/1 5:02:31

数字员工是什么?熊猫智汇在提升AI销售工具中的作用是什么?

数字员工通过自动化和智能化的管理工具&#xff0c;如AI销冠系统&#xff0c;显著提升了企业的业务流程效率。它能够快速处理客户信息&#xff0c;减少人工干预&#xff0c;从而降低人力成本。企业利用数字员工可以实现高效率的客户沟通、数据处理和市场分析&#xff0c;让运营…

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

企业级AI智能体自动化评估:实用指南与最佳实践!

一、AI 智能体评估实用指南 了解如何借助结构化评估框架对企业级 AI 智能体进行评估&#xff0c;涵盖模型测试、产品测试、场景化分析、性能指标及持续监控等方面。 二、AI 智能体评估实用指南 若在部署 AI 智能体时缺乏完善的评估策略&#xff0c;这不仅是技术层面的疏漏&…

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

14、PF 日志、监控、统计及配置优化

PF 日志、监控、统计及配置优化 1. 日志设置与处理 在网络配置中,日志记录是了解系统行为的重要手段。设置 syslogd 来处理数据相对简单,只需选择日志设施、日志级别和操作,然后将相应的行添加到 /etc/syslog.conf 文件中。例如,假设已将系统日志记录器设置为在 log…

作者头像 李华
网站建设 2026/4/27 10:38:21

Dubbo面试必看:同一个服务多个注册如何直连?

文章目录同一个服务多个注册的情况下可以直连某一个服务吗&#xff1f;引言&#xff1a;为什么要关心同一个服务的多个注册&#xff1f;第一部分&#xff1a;同一个服务多个注册的背后逻辑Dubbo 的服务发现机制第二部分&#xff1a;是否可以直接连接某一个服务实例&#xff1f;…

作者头像 李华
网站建设 2026/4/13 9:33:16

Vulkan教程(十九):多帧并行:消除CPU与GPU空闲的核心优化

目录 一、定义并行帧数上限 二、资源多实例化改造 2.1 批量创建命令缓冲 2.2 批量创建同步对象 三、帧索引管理:实现资源循环复用 四、修改渲染循环:实现多帧并行 核心逻辑解析 五、同步方案拓展:时间线信号量 六、总结与后续 当前我们的渲染循环存在一个明显缺陷:…

作者头像 李华