剑指 Offer 51. 数组中的逆序对
剑指 Offer 51. 数组中的逆序对
递归解法(超内存)
public class Algorithm {
public static void main(String[] args) {
int[] nums = {7,5,6,4};
System.out.println(new Solution().reversePairs(nums));
}
}
class Solution {
int start = 0;
public int reversePairs(int[] nums) {
if (nums == null || nums.length == 0 || nums.length == 1){
return 0;
}
int[] temp = new int[nums.length - 1];
System.arraycopy(nums, start + 1, temp, 0, nums.length - 1);
int res1 = reversePairs(temp);
int res2 = 0;
for (int i = start + 1; i < temp.length + 1; i++) {
if (nums[start] > nums[i]){
res2++;
}
}
return res1 + res2;
}
}
归并排序解法
注意:不能将方法定义为static,否则LeetCode不能识别
import java.util.Arrays;
public class Algorithm {
public static void main(String[] args) {
int[] nums = {4, 5, 6, 7};
System.out.println(new Solution().reversePairs(nums));
}
}
class Solution {
/**
* 定义全局变量res统计总的逆序对
*/
int res = 0;
public int reversePairs(int[] nums) {
int[] temp = Arrays.copyOf(nums, nums.length);
sort(nums, 0, nums.length - 1, temp);
return res;
}
public void sort(int[] arr, int left, int right, int[] temp){
if (left >= right){
return;
}
int mid = left + (right - left) / 2;
sort(arr, left, mid, temp);
sort(arr, mid + 1, right, temp);
if (arr[mid] > arr[mid + 1]) {
merge(arr, left, mid, right, temp);
}
}
public void merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left;
int j = mid + 1;
System.arraycopy(arr, left, temp, left, right - left + 1);
for (int n = left; n < right + 1; n++) {
if (i == mid + 1){
arr[n] = temp[j];
j++;
}
else if (j == right + 1) {
arr[n] = temp[i];
i++;
}
else if (temp[i] <= temp[j]) {
arr[n] = temp[i];
i++;
}
else{
arr[n] = temp[j];
/**
* 只有当temp[i] > temp[j],也就是左边区间的元素比右边大时,才会有逆序对
* 此时,左边所有剩下的元素,都和右边当前元素形成逆序对
*/
res = res + mid - i + 1;
j++;
}
}
}
}
不使用全量变量,而是用函数的返回值来统计逆序对,少维护一个全局变量,做到函数式编程
import java.util.Arrays;
public class Algorithm {
public static void main(String[] args) {
int[] nums = {4, 5, 6, 7};
System.out.println(new Solution().reversePairs(nums));
}
}
class Solution {
public int reversePairs(int[] nums) {
int[] temp = Arrays.copyOf(nums, nums.length);
return sort(nums, 0, nums.length - 1, temp);
}
public int sort(int[] arr, int left, int right, int[] temp){
if (left >= right){
return 0;
}
/**
* 将res变量定义在函数内部,实现函数式编程
*/
int res = 0;
int mid = left + (right - left) / 2;
res += sort(arr, left, mid, temp);
res += sort(arr, mid + 1, right, temp);
if (arr[mid] > arr[mid + 1]) {
res += merge(arr, left, mid, right, temp);
}
return res;
}
public int merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left;
int j = mid + 1;
int res = 0;
System.arraycopy(arr, left, temp, left, right - left + 1);
for (int n = left; n < right + 1; n++) {
if (i == mid + 1){
arr[n] = temp[j];
j++;
}
else if (j == right + 1) {
arr[n] = temp[i];
i++;
}
else if (temp[i] <= temp[j]) {
arr[n] = temp[i];
i++;
}
else{
arr[n] = temp[j];
res = res + mid - i + 1;
j++;
}
}
return res;
}
}
自底向上归并排序解法
import java.util.Arrays;
public class Algorithm {
public static void main(String[] args) {
int[] nums = {7,5,6,4};
System.out.println(new Solution().reversePairs(nums));
}
}
class Solution {
public int reversePairs(int[] nums) {
int[] temp = Arrays.copyOf(nums, nums.length);
return sort(nums, temp);
}
public int sort(int[] arr, int[] temp){
int size;
int res = 0;
//arr[i, i + size - 1]和arr[i + size, i + size + size - 1]
for (size = 1; size < arr.length; size *= 2) {
for (int i = 0; i + size < arr.length; i += 2 * size) {
if (arr[i + size - 1] > arr[i + size]){
res += merge(arr, i, i + size - 1, Math.min(i + 2 * size - 1, arr.length - 1), temp);
}
}
}
return res;
}
public int merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left;
int j = mid + 1;
int res = 0;
System.arraycopy(arr, left, temp, left, right - left + 1);
for (int n = left; n < right + 1; n++) {
if (i == mid + 1){
arr[n] = temp[j];
j++;
}
else if (j == right + 1) {
arr[n] = temp[i];
i++;
}
else if (temp[i] <= temp[j]) {
arr[n] = temp[i];
i++;
}
else{
arr[n] = temp[j];
res += mid - i + 1;
j++;
}
}
return res;
}
}
https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/