leetcode 剑指 Offer 51. 数组中的逆序对
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4]
输出: 5
限制:
0 <= 数组长度 <= 50000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
采用二路归并排序的思想。
每次合并arr1,arr2的时候,做一步count的统计:
例如 arr1 = [2,4,7]; arr2 = [1,3,4,5]
若 arr1[n] > arr2[m] 表明 arr1.length - n + 1 个数字比 arr2[m]大, 所以 count += (arr1.length - n + 1)。
private int[] item; private int count = 0; public int reversePairs(int[] nums) { if (nums == null || nums.length < 2) { return 0; } int length = nums.length; item = new int[length]; find(nums, 0, length - 1); return count; } private void find(int[] nums, int st, int end) { if (st >= end) { return; } int m = st + ((end - st) >> 1); find(nums, st, m); find(nums, m + 1, end); int i = st; int j = m + 1; int index = 0; while (i <= m && j <= end) { if (nums[i] > nums[j]) { item[index++] = nums[j++]; count += (m - i + 1); } else { item[index++] = nums[i++]; } } while (i <= m) { item[index++] = nums[i++]; } while (j <= end) { item[index++] = nums[j++]; } index = 0; for (int k = st; k <= end; k++) { nums[k] = item[index++]; } }