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

分治-归并-493.翻转对-力扣(LeetCode)

一、题目解析

1、i<j且nums[i]>2*nums[j],(i,j)记作一个翻转对

2、nums长度不会超过50000

3、nums中所有元素都在32位整数范围内

二、算法原理

解法1:暴力枚举 O(N^2)

固定一个数,枚举另一个数

解法2:分治 O(N*logN)

计算翻转对 (利用单调性,使用同向双指针)

方法1:计算当前元素后面,有多少元素的两倍比我小(降序)

由于降序,nums[cur1]>nums[cur2]*2,即nums[cur1]比cur2后面的所有数大,所以cur2~right的个数为right-cur2+1

方法2:计算当前元素之前,有多少元素的一般比我大(升序)

除2.0为了避免除不尽的情况,由于升序,nums[cur1]/2.0>nums[cur2],nums[cur2]比cur1后面的所有数小,所以cur1~mid的个数为mid-cur1+1

合并两个有序数组

在升序中,tmp[i++] = nums[cur1]<=nums[cur2] ? nums[cur1++] : nums[cur2++]

在降序中,tmp[i++] = nums[cur1]<=nums[cur2] ? nums[cur2++] : nums[cur1++]

三、代码示例

解法2:降序

 int tmp[50005];
public://降序int reversePairs(vector<int>& nums){return mergeSort(nums,0,nums.size()-1);}int mergeSort(vector<int>& nums,int left,int right){int ret = 0;if(left>=right) return 0;int mid = (left+right)>>1;ret += mergeSort(nums,left,mid);ret += mergeSort(nums,mid+1,right);//统计翻转对int cur1 = left,cur2 = mid+1;while(cur1<=mid){while(cur2<=right && nums[cur1]/2.0 <= nums[cur2]) cur2++;if(cur2>right) break;ret += right-cur2+1;cur1++;}int curr1 = left,curr2 = mid+1,i = 0;while(curr1<=mid && curr2<=right)tmp[i++] = nums[curr1]<=nums[curr2] ? nums[curr2++] : nums[curr1++];//处理未遍历完while(curr1<=mid) tmp[i++] = nums[curr1++];while(curr2<=right) tmp[i++] = nums[curr2++];//还原for(int i = left;i<=right;i++)nums[i] = tmp[i-left];return ret;}

这里不是nums[cur2]*2原因是,虽然都是32位整数范围内,但是*2可能会导致积超过32位的范围,所以/2.0

解法2:升序

int tmp[50005];
public:
//升序int reversePairs(vector<int>& nums){return mergeSort(nums,0,nums.size()-1);}int mergeSort(vector<int>& nums,int left,int right){int ret = 0;if(left>=right) return 0;int mid = (left+right)>>1;ret += mergeSort(nums,left,mid);ret += mergeSort(nums,mid+1,right);//统计翻转对int cur1 = left,cur2 = mid+1;while(cur2<=right){while(cur1<=mid && nums[cur1]/2.0 <= nums[cur2]) cur1++;if(cur1>mid) break;ret += mid-cur1+1;cur2++;}int curr1 = left,curr2 = mid+1,i = 0;while(curr1<=mid && curr2<=right)tmp[i++] = nums[curr1]<=nums[curr2] ? nums[curr1++] : nums[curr2++];//处理未遍历完while(curr1<=mid) tmp[i++] = nums[curr1++];while(curr2<=right) tmp[i++] = nums[curr2++];//还原for(int i = left;i<=right;i++)nums[i] = tmp[i-left];return ret;}

看到最后,如果对您有所帮助,还请点赞、收藏和关注,我们下期再见!

http://www.lryc.cn/news/625048.html

相关文章:

  • Flutter 自定义 Switch 切换组件完全指南
  • Python 面向对象三大特性详解(与 C++ 对比)
  • Android Handler 线程执行机制
  • flutter项目适配鸿蒙
  • 【展厅多媒体】互动地砖屏怎么提升展厅互动感的?
  • 2025年最新美区Apple ID共享账号免费分享(持续更新)
  • 数组学习2
  • Java面试题储备14: 使用aop实现全局日志打印
  • 【HTML】document api
  • Vue 3中watch的返回值:解锁监听的隐藏技巧
  • C++---有符号和无符号整数的位移操作
  • RabbitMQ:数据隔离
  • kafka 冲突解决 kafka安装
  • Unity进阶--C#补充知识点--【Unity跨平台的原理】Mono与IL2CPP
  • 探索性测试:灵活找Bug的“人肉探测仪”
  • MongoDB Windows 系统实战手册:从配置到数据处理入门
  • keil错误:Error: failed to execute ‘D:\Keil\C51\BIN\BIN\A51.EXE‘
  • 【智慧工地源码】智慧工地云平台系统,涵盖安全、质量、环境、人员和设备五大管理模块,实现实时监控、智能预警和数据分析。
  • PYTHON让繁琐的工作自动化-猜数字游戏
  • 从数据汇总到高级分析,SQL 查询进阶实战(下篇)—— 分组、子查询与窗口函数全攻略
  • 车e估牵头正式启动乘用车金融价值评估师编制
  • CoRL 2025|隐空间扩散世界模型LaDi-WM大幅提升机器人操作策略的成功率和跨场景泛化能力
  • 从「行走」到「思考」:机器人进化之路与感知—决策链路的工程化实践
  • 第4.3节:awk正则表达式详解-特殊字符
  • Pytest测试框架基础及进阶
  • 前端css学习笔记7:各种居中布局空白问题
  • Jenkins全链路教程——Jenkins调用Maven构建项目
  • IoT/透过oc_lwm2m和at源码,分析NB-IoT通信模组和主板MCU之间的通信过程
  • 【Jenkins】03 - 自动构建和docker构建
  • 【opencv-Python学习笔记(7):图像平滑处理】