面试题51. 数组中的逆序对(困难)
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4]
输出: 5
限制:
0 <= 数组长度 <= 50000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof
思路:
归并排序,需要了解归并排序解题模板
分治思想:
- 分两块,左右
- 分别计算,左边,右边
- 再计算横跨左右的
代码1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| class Solution { public int reversePairs(int[] nums) { return mergeSort(nums,0,nums.length-1); } public int mergeSort(int[] nums,int left,int right){ if(left>=right) return 0; int mid = (right+left)>>1; return mergeSort(nums,left,mid)+mergeSort(nums,mid+1,right)+merge(nums,left,mid,right); } public int merge(int[] nums,int left,int mid,int right){ int count =0; int l = left; int r = mid +1; int index = 0; int[] assist = new int[right-left+1]; while(l<=mid && r<=right){ if(nums[l]>nums[r]) count += mid-l+1; assist[index++] = nums[l]<=nums[r]?nums[l++]:nums[r++]; } while(l<=mid) assist[index++] = nums[l++]; while(r<=right) assist[index++] = nums[r++]; for (int i = 0,j=left; i < assist.length; i++,j++) { nums[j] = assist[i]; } return count; } }
|