LeetCode 剑指 Offer 51. 数组中的逆序对
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4]
输出: 5
LeetCode 剑指 Offer 51. 数组中的逆序对
提示:
一、解题关键词
二、解题报告
1.思路分析
双层for 循环暴力
会超时 时间复杂度O(n^2)
归并排序
递归拆分数组,拆分成单个元素的数组
拆分完成之后,进行合并 并累加右数组合并到左数据的过程中 符合逆序的数组个数
2.时间复杂度
0(nlogn)
3.代码示例
class Solution {
public int reversePairs(int[] nums) {
int len = nums.length;
if(len < 2){return 0;}
int [] copy = Arrays.copyOf(nums,len);
int[] tmp = new int[len];
return reversePairs(copy,0,len - 1,tmp);
}
//递归计算
int reversePairs(int[] nums,int left,int right,int[] tmp){
if(left == right){return 0;}
int mid = left + (right - left) / 2;
int leftPair = reversePairs(nums,left,mid,tmp);
int rightPair = reversePairs(nums,mid + 1,right,tmp);
if(nums[mid] < nums[mid + 1]){
return leftPair + rightPair;
}
int crossPairs = mergeAndCount(nums,left,mid,right,tmp);
return leftPair + rightPair +crossPairs;
}
//进行合并 获取对数
int mergeAndCount(int[] nums,int left,int mid,int right,int[] tmp){
for(int i = left; i <= right; i++){
tmp[i] = nums[i];
}
int i = left;
int j = mid + 1;
int count = 0;
for(int k = left;k<= right;k++){
if(i == mid + 1){
nums[k] = tmp[j];
j++;
}else if(j == right + 1){
nums[k] = tmp[i];
i++;
}else if(tmp[i] <= tmp[j]){
nums[k] = tmp[i];
i++;
}else {
nums[k] = tmp[j];
j++;
count +=(mid - i + 1);
}
}
return count;
}
}
2.知识点
归并排序 & 递归 进行归并的时候 注意下标控制
总结
快速排序 & 归并排序 可以阶段性的看到排序效果