算法——计算数组中的逆序对
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
输入: [7,5,6,4]
输出: 5
链接: leetcode.
解题思路:利用归并排序的思想。在归并排序中,需要通过两个指针比较前后两个元素的大小,当前元素大于后元素时,这就是一个有效的逆序对。同时,如果某一前元素大于后元素,则前段元素区间中,该元素的后面元素也会大于后段区间中该后元素,所以,也需要将这一部分逆序对计算上。
这样做会不会产生重复的逆序对计算呢?答案是不会的,每次比较的两个相等长度的段中的元素,随着递归,前面计算的段已经被合并,段的长度会增长,之后比较的元素一定不会再被重复比较,这样就不会产生重复计算。
下面提供了两种做法,还是推荐递归做法,这样没用考虑很多边界问题。
- 递归做法
class Solution {
int res = 0;
public int reversePairs(int[] nums) {
merge(nums, 0, nums.length - 1);
return res;
}
public void merge(int[] nums, int l, int r) {
if(l >= r) return;
int mid = l + r >> 1;
merge(nums, l, mid);
merge(nums, mid + 1, r);
int i = l, j = mid + 1;
List<Integer> temp = new ArrayList<>();
while(i <= mid && j <= r) {
if(nums[i] <= nums[j]) {
temp.add(nums[i]);
i++;
} else {
// 逆序对计算,数量应当是i及i到mid之间的元素数量
// 因为i大于j位置的元素,那i之后的元素也一定大于j位置的元素
res += mid - i + 1;
temp.add(nums[j]);
j++;
}
}
while(j <= r) {
temp.add(nums[j]);
j++;
}
while(i <= mid) {
temp.add(nums[i]);
i++;
}
i = l;
while(i <= r) {
nums[i] = temp.get(i - l);
i++;
}
}
}
- 非递归
class Solution {
public int reversePairs(int[] nums) {
int n = nums.length;
if(n == 0 || n == 1) return 0;
int res = 0;
for(int len = 1; len < n; len *= 2) {
for(int i = 0; i < n; i += 2 * len) {
List<Integer> temp = new ArrayList<>();
int l = i, r = i + len;
int mid = i + len;
while(l < mid && r < i + len * 2 && r < n) {
if(nums[l] > nums[r]) {
res += mid - l;
temp.add(nums[r]);
r++;
} else{
temp.add(nums[l]);
l++;
}
}
while(l < mid && l < n) {
temp.add(nums[l++]);
}
while(r < i + len * 2 && r < n) {
temp.add(nums[r++]);
}
for(int j = 0; j < temp.size(); j++) {
nums[j + i] = temp.get(j);
}
}
}
return res;
}
}
本文作者:lippon
本文链接:https://www.cnblogs.com/lippon/p/14117688.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
算法
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· Sdcb Chats 技术博客:数据库 ID 选型的曲折之路 - 从 Guid 到自增 ID,再到
· .NET Core GC压缩(compact_phase)底层原理浅谈
· Winform-耗时操作导致界面渲染滞后
· Phi小模型开发教程:C#使用本地模型Phi视觉模型分析图像,实现图片分类、搜索等功能
· 语音处理 开源项目 EchoSharp