题目

结果

代码
递归+归并排序
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 39 40 41 42 43 44 45 46 47 48 49
| class Solution { public int reversePairs(int[] nums) { if (nums.length == 0) { return 0; } return reversePairs(nums, 0, nums.length - 1); }
private int reversePairs(int[] nums, int left, int right) { if (left == right) { return 0; } int mid = (left + right) / 2; int ans = reversePairs(nums, left, mid) + reversePairs(nums, mid + 1, right);
int i = left, j = mid + 1; while (i <= mid) { while (j <= right && (long) nums[i] > (long) nums[j] * 2) { j++; } ans += j - mid - 1; i++; }
int[] sorted = new int[right - left + 1]; i = left; j = mid + 1; int k = 0; while (i <= mid || j <= right) { if (i > mid) { sorted[k++] = nums[j++]; } else if (j > right) { sorted[k++] = nums[i++]; } else { if (nums[i] < nums[j]) { sorted[k++] = nums[i++]; } else { sorted[k++] = nums[j++]; } } } for (i = 0; i < sorted.length; i++) { nums[left + i] = sorted[i]; }
return ans; } }
|
递归+快排
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
| class Solution { public int reversePairs(int[] nums) { if (nums.length == 0) { return 0; } return reversePairs(nums, 0, nums.length - 1); }
private int reversePairs(int[] nums, int left, int right) { if (left == right) { return 0; } int mid = (left + right) / 2; int ans = reversePairs(nums, left, mid) + reversePairs(nums, mid + 1, right);
int i = left, j = mid + 1; while (i <= mid) { while (j <= right && (long) nums[i] > (long) nums[j] * 2) { j++; } ans += j - mid - 1; i++; }
Arrays.sort(nums, left, right + 1); return ans; } }
|
凭什么归并排序要比快排快上一些呢?
这跟待排序数组的特点有关,待排序数组等分成两个数组,两个数组各自有序。
而数组这种特点很适合归并排序,两个数组各自有序,可以直接归并。
复杂度
时间复杂度:O(N log N)
空间复杂度:O(N),归并。O(log N),快排。