在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007
数据范围: 对于 的数据,
对于 的数据,
数组中所有数字的值满足
要求:空间复杂度 ,时间复杂度
题目保证输入的数组中没有的相同的数字
[1,2,3,4,5,6,7,0]
7
[1,2,3]
0
public class Solution { public int InversePairs(int[] nums) { int left = 0, right = nums.length - 1; return (int)(mergeSort(nums, left, right) % 1000000007); } private long mergeSort(int[] nums, int left, int right) { if (left == right) { return 0; } int mid = left + ((right - left) >> 1); long x1 = mergeSort(nums, left, mid); long x2 = mergeSort(nums, mid + 1, right); long x3 = merge(nums, left, mid, mid + 1, right); return x1 + x2 + x3; } private long merge(int[] nums, int l1, int l2, int r1, int r2) { int[] temp = new int[r2 - l1 + 1]; int i = 0; int l = l1; long count = 0; while (l1 <= l2 && r1 <= r2) { if (nums[l1] > nums[r1]) { count = count + r2 - r1 + 1; temp[i++] = nums[l1++]; } else { temp[i++] = nums[r1++]; } } while (l1 <= l2) { temp[i++] = nums[l1++]; } while (r1 <= r2) { temp[i++] = nums[r1++]; } // 放回原来的数组 i = 0; for (int i1 = l; i1 <= r2; i1++) { nums[i1] = temp[i++]; } return count; } }
归并排序
public class Solution { public static final int MOD = 1000000007; public int InversePairs (int[] nums) { return mergeSort(nums, 0, nums.length - 1); } public int mergeSort(int[] nums, int l, int r) { if (l == r) { return 0; } int mid = (l + r) >> 1; int lres = mergeSort(nums, l, mid); int rres = mergeSort(nums, mid + 1, r); int left = l, right = mid + 1, ans = (lres + rres) % MOD; int[] tmp = new int[r - l + 1]; int idx = 0; while (left <= mid && right <= r) { if (nums[left] <= nums[right]) { tmp[idx++] = nums[left++]; } else { tmp[idx++] = nums[right++]; ans = (ans + mid - left + 1) % MOD; } } while (left <= mid) tmp[idx++] = nums[left++]; while (right <= r) tmp[idx++] = nums[right++]; for (int i = 0; i < idx; i++) { nums[l + i] = tmp[i]; } return ans; } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param nums int整型一维数组 * @return int整型 */ public int InversePairs (int[] nums) { long total=0; for (int i = 0; i < nums.length; i++) { for (int j = i+1; j <nums.length; j++) { if (nums[i]>nums[j]){ total++; } } } return (int) (total%1000000007); } }
public class Solution { public int InversePairs(int [] array) { if (array == null || array.length == 0) return -1; int count = 0; for (int i = 0; i < array.length - 1; i++) { for (int j = i; j < array.length - 1; j++) { if (array[i] > array[j + 1]) count++; } } return count % 1000000007; } }
public class Solution { public int InversePairs(int [] array) { if(array.length == 0) return 0; long P =0L; for(int i =0; i < array.length - 1; i++) for(int j = i + 1; j < array.length; j++){ if(array[i] > array[j]) P++; } return (int)(P % 1000000007); } }这个代码是不是时间复杂度是O(n^2)?虽然通过了,冒泡排序再怎么优化都是n^2吗?
public class Solution { public int InversePairs(int [] array) { if(null == array || array.length <= 1){ return 0; } return getCount(array,0,array.length-1,new int[array.length]); } private int getCount(int[] array,int start,int end,int[] copy){ if(start >= end) { copy[start] = array[start]; return 0; } int count = 0; int mid = start + (end - start) / 2; count += getCount(array,start,mid,copy); count += getCount(array,mid + 1,end,copy); int i = mid; int j = end; int copyIndex = end; while (i >= start && j > mid){ if(array[i] > array[j]){ copy[copyIndex--] = array[i--]; count += j - mid; count = count % 1000000007; } else{ copy[copyIndex--] = array[j--]; } } while (i >= start){ copy[copyIndex--] = array[i--]; } while (j > mid){ copy[copyIndex--] = array[j--]; } for(int k = start;k <= end;k++){ array[k] = copy[k]; } return count; } }
//归并排序Java版 public class Solution { int count=0; public int InversePairs(int [] array) { mergeSort(array,0,array.length-1); return count; } public void mergeSort(int [] array, int left, int right){ if(left >= right) return; int mid = (left+right)/2; mergeSort(array, left, mid); mergeSort(array, mid+1, right); merge(array, left, mid, right); } public void merge(int [] array, int left, int mid, int right){ int[] temp=new int[right-left+1]; int i=left, j=mid+1; int t=0; while(i<=mid && j<=right){ if(array[i]<=array[j]){ temp[t++]=array[i++]; }else{ count=count+(mid-i+1); count%=1000000007; //在这里取模 temp[t++]=array[j++]; } } while(i<=mid){ temp[t++]=array[i++]; } while(j<=right){ temp[t++]=array[j++]; } for(int k=0;k<temp.length;k++){ array[left+k]=temp[k]; } } }
public class Solution { public int InversePairs(int [] array) { if (array == null || array.length <= 0 ) { return 0; } int[] temp = new int[array.length]; return sort(array, 0, array.length-1, temp) % 1000000007; } private int sort(int[] array, int left, int right, int[] temp) { if (left == right) { return 0; } int mid = (right - left) / 2 + left; int leftPairCount = sort(array, left, mid, temp); int rightPairCount = sort(array, mid + 1, right, temp); int tmpPairCount = merge(array, left, mid, right, temp); return leftPairCount + rightPairCount + tmpPairCount; } private int merge(int[] array, int left, int mid, int right, int[] temp) { int start1 = left; int start2 = mid + 1; int index = 0; int computeReversePairs = 0; while (start1 <= mid && start2 <= right) { if (array[start1] <= array[start2]) { temp[left + index] = array[start1]; start1++; } else { temp[left + index] = array[start2]; start2++; computeReversePairs = (computeReversePairs+(mid-start1+1))%1000000007; } index++; } while (start1 <= mid) { temp[left + index] = array[start1]; start1++; index++; } while (start2 <= right) { temp[left + index] = array[start2]; start2++; index++; } //将temp覆盖原来的数组中的顺序 while (left <= right) { array[left] = temp[left]; left++; } return computeReversePairs; } }
public class Solution { public int mod = 1000000007; public int InversePairs(int [] arr) { if(arr == null || arr.length <= 1){ return 0; } int[] temp = new int[arr.length]; return InversePairs(arr, 0, arr.length - 1, temp); } public int InversePairs(int [] arr, int left, int right,int[] temp) { if(left >= right){ return 0; } int mid = left + (right - left ) / 2; int val1 = (InversePairs(arr, left, mid, temp) + InversePairs(arr, mid + 1, right, temp)) % mod; if(arr[mid] <= arr[mid + 1]){ return val1; } int l = left, r = mid + 1 ,count = 0, tempI = 0; while (l <= mid && r <= right){ if(arr[l] > arr[r]){ temp[tempI] = arr[r]; r++; // 左边比右边绝对大时 count+= 左边当前共有多少数的数量 count += mid + 1 - l; }else{ temp[tempI] = arr[l]; l++; } tempI++; } while (l <= mid){ temp[tempI] = arr[l]; l++; tempI++; } while (r <= right){ temp[tempI] = arr[r]; r++; tempI++; } tempI = 0; for (int i = left; i <= right; i++,tempI++) { arr[i] = temp[tempI]; } return (val1 + count) % mod; } }
public class Solution { int ans = 0; public int InversePairs(int [] nums) { if(nums.length < 1) return 0; mergeSort(nums, 0, nums.length - 1); return ans; } void mergeSort(int[] nums, int left, int right){ if(left >= right) return; int mid = left + (right - left) / 2; mergeSort(nums, left, mid); mergeSort(nums, mid + 1, right); merge(nums, left, mid , right); } void merge(int[] nums, int left, int mid, int right) { int[] copy = new int[right - left + 1]; int l1 = left, l2 = mid + 1, idx = 0; while(l1 <= mid && l2 <= right) { if(nums[l1] < nums[l2]) { copy[idx++] = nums[l1++]; }else{ copy[idx++] = nums[l2++]; ans += mid - l1 + 1; ans %= 1000000007; } } while(l1 <= mid) copy[idx++] = nums[l1++]; while(l2 <= right) copy[idx++] = nums[l2++]; for(int i = 0; i < copy.length; ++i) { nums[left + i] = copy[i]; } } }