剑指 Offer 51. 数组中的逆序对
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4]
输出: 5
时间复杂度:O(NlogN),空间复杂度:O(N)
class Solution { public int reversePairs(int[] nums) { //写一个归并排序,在每次合并的时候对两组子数组进行计算逆序对,累加计数 int len = nums.length; if(len<2) return 0; int[] temp = new int[len]; int[] copy = new int[len]; for(int i = 0;i<len;i++) copy[i] = nums[i]; return process(copy,0,len-1,temp); } public int process(int[] nums,int left,int right,int[] temp) { if(left == right) return 0; int mid = left+(right-left)/2; int leftcount = process(nums,left,mid,temp); int rightcount = process(nums,mid+1,right,temp); if(nums[mid] <= nums[mid+1]) return leftcount+rightcount; int mCount = merger(nums, left, mid, right, temp); return leftcount + rightcount +mCount; } public int merger(int[] nums,int left,int mid,int right,int[] temp) { for(int i = left;i<=right;i++) temp[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] = temp[j];j++; } else if(j == right+1) { nums[k] = temp[i];i++; } else if(temp[i] <= temp[j]) { nums[k] = temp[i];i++; } else { nums[k] = temp[j];j++; count+=mid-i+1;//归并排序过程中只多了这一句,移动j时记录前面有多少数组成逆序对 } } return count; } }