当前位置: 首页 > 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.dtcms.com/a/337232.html

相关文章:

  • 艺术品与收藏直播驱动数字化鉴赏与交易
  • 设计模式笔记_行为型_访问者模式
  • 双通道审核智能合约更新路径:基于区块链与AI融合的编程范式分析
  • MATLAB建模与可视化技术文档:从二维到三维
  • snprintf
  • 《Python学习之使用标准库:从入门到实战》
  • 104、【OS】【Nuttx】【周边】文档构建渲染:安装 Sphinx 扩展(上)
  • 从零到一构建企业级GraphRAG系统:GraphRag.Net深度技术解析
  • Python Ovito统计多晶晶粒数量
  • 领域驱动设计(DDD)中的“核心领域逻辑与基础设施分离”原则
  • Maven 生命周期和插件
  • RocketMQ是什么?
  • Day7--滑动窗口与双指针--1695. 删除子数组的最大得分,2958. 最多 K 个重复元素的最长子数组,2024. 考试的最大困扰度
  • 消息队列中的推模式与拉模式
  • C++/Java双平台表单校验实战:合法性+长度+防重复+Tab顺序四重守卫
  • 【从0开始学习Java | 第14篇】集合(上)
  • Day8--滑动窗口与双指针--1004. 最大连续1的个数 III,1658. 将 x 减到 0 的最小操作数,3641. 最长半重复子数组
  • 考问通系统测试分析报告
  • Golang 语言中的指针操作
  • Android中使用RxJava实现网络请求与缓存策略
  • 实习两个月总结
  • 通义万相Wan2.1- 阿里推出的开源视频生成大模型
  • 从哲学(业务)视角看待数据挖掘:从认知到实践的螺旋上升
  • Elasticsearch查询中的track_total_hits参数
  • 【网络安全实验报告】实验五:网络嗅探及安全性分析
  • 在阿里云 CentOS Stream 9 64位 UEFI 版上离线安装 Docker Compose
  • CentOS 7更换国内镜像源
  • CentOS 7安装OpenVASGVM指南
  • 国产!全志T113-i 双核Cortex-A7@1.2GHz 工业开发板—ARM + DSP、RISC-V核间通信开发案例
  • [数据结构] ArrayList 与 顺序表