Algorithm 数组中的倒计数
我正在设计一个算法来完成以下工作:给定数组Algorithm 数组中的倒计数,algorithm,Algorithm,我正在设计一个算法来完成以下工作:给定数组A[1…n],对于每个IA[j]。我使用合并排序并将数组A复制到数组B,然后比较这两个数组,但是我很难看到如何使用它来找到反转数。任何提示或帮助都将不胜感激。简单的O(n^2)答案是使用嵌套循环,并为每个反转增加一个计数器 int counter = 0; for(int i = 0; i < n - 1; i++) { for(int j = i+1; j < n; j++) { if( A[i] >
A[1…n]
,对于每个I
,找到所有的反转对,使得A[I]>A[j]
。我使用合并排序并将数组A复制到数组B,然后比较这两个数组,但是我很难看到如何使用它来找到反转数。任何提示或帮助都将不胜感激。简单的O(n^2)答案是使用嵌套循环,并为每个反转增加一个计数器
int counter = 0;
for(int i = 0; i < n - 1; i++)
{
for(int j = i+1; j < n; j++)
{
if( A[i] > A[j] )
{
counter++;
}
}
}
return counter;
int计数器=0;
对于(int i=0;iA[j])
{
计数器++;
}
}
}
返回计数器;
现在我想你想要一个更有效的解决方案,我会考虑的。我通过以下方法在O(n*logn)时间内找到了它
def binarySearch(alist, item):
first = 0
last = len(alist) - 1
found = False
while first <= last and not found:
midpoint = (first + last)//2
if alist[midpoint] == item:
return midpoint
else:
if item < alist[midpoint]:
last = midpoint - 1
else:
first = midpoint + 1
def solution(A):
B = list(A)
B.sort()
inversion_count = 0
for i in range(len(A)):
j = binarySearch(B, A[i])
while B[j] == B[j - 1]:
if j < 1:
break
j -= 1
inversion_count += j
B.pop(j)
if inversion_count > 1000000000:
return -1
else:
return inversion_count
print solution([4, 10, 11, 1, 3, 9, 10])
2a。将反转数累加到计数器变量num_反转
2b。从阵列A和阵列B中的相应位置删除A[1]谢谢你的帮助。在一张纸上写出样本数组确实有助于将问题形象化。实际上,对于家庭作业,我有一个类似的问题。我被限制它必须有O(nlogn)效率 我使用了您提出的使用Mergesort的想法,因为它已经具有正确的效率。我刚刚在合并函数中插入了一些代码,基本上是: 无论何时,只要将右侧数组中的一个数字添加到输出数组中,我就会将左侧数组中剩余的数字添加到反转总数中 这对我来说很有意义,因为我已经考虑够了。您正在计算在任何数字之前有多少次出现更大的数字 hth.查看以下内容: 我希望它能给你正确的答案
- 2-3反转部分(d)
- 它的运行时间是O(nlogn)
- 下面是java中的O(n logn)解决方案
long merge(int[] arr, int[] left, int[] right) {
int i = 0, j = 0, count = 0;
while (i < left.length || j < right.length) {
if (i == left.length) {
arr[i+j] = right[j];
j++;
} else if (j == right.length) {
arr[i+j] = left[i];
i++;
} else if (left[i] <= right[j]) {
arr[i+j] = left[i];
i++;
} else {
arr[i+j] = right[j];
count += left.length-i;
j++;
}
}
return count;
}
long invCount(int[] arr) {
if (arr.length < 2)
return 0;
int m = (arr.length + 1) / 2;
int left[] = Arrays.copyOfRange(arr, 0, m);
int right[] = Arrays.copyOfRange(arr, m, arr.length);
return invCount(left) + invCount(right) + merge(arr, left, right);
}
长合并(int[]arr,int[]left,int[]right){
int i=0,j=0,count=0;
而(i }else if(left[i]注意杰弗里·欧文的答案是错误的
一个数组中的反转数是为了对数组进行排序而必须移动的总距离元素数的一半。因此,可以通过对数组进行排序,保持产生的置换p[i],然后计算abs(p[i]-i)/2之和来计算反转数。这需要O(n logn)时间,这是最优的
在中给出了另一种方法。该方法相当于max(0,p[i]-i)之和,它等于abs(p[i]-i])/2之和,因为向左移动的总距离元素等于向右移动的总距离元素
以序列{3,2,1}为例。有三个倒数:(3,2),(3,1),(2,1),所以倒数是3。然而,根据引用的方法,答案应该是2。因为这是一个老问题,我将用C提供我的答案
#include <stdio.h>
int count = 0;
int inversions(int a[], int len);
void mergesort(int a[], int left, int right);
void merge(int a[], int left, int mid, int right);
int main() {
int a[] = { 1, 5, 2, 4, 0 };
printf("%d\n", inversions(a, 5));
}
int inversions(int a[], int len) {
mergesort(a, 0, len - 1);
return count;
}
void mergesort(int a[], int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
mergesort(a, left, mid);
mergesort(a, mid + 1, right);
merge(a, left, mid, right);
}
}
void merge(int a[], int left, int mid, int right) {
int i = left;
int j = mid + 1;
int k = 0;
int b[right - left + 1];
while (i <= mid && j <= right) {
if (a[i] <= a[j]) {
b[k++] = a[i++];
} else {
printf("right element: %d\n", a[j]);
count += (mid - i + 1);
printf("new count: %d\n", count);
b[k++] = a[j++];
}
}
while (i <= mid)
b[k++] = a[i++];
while (j <= right)
b[k++] = a[j++];
for (i = left, k = 0; i <= right; i++, k++) {
a[i] = b[k];
}
}
#包括
整数计数=0;
整数反转(整数a[],整数len);
void mergesort(int a[],int left,int right);
无效合并(int a[],int left,int mid,int right);
int main(){
inta[]={1,5,2,4,0};
printf(“%d\n”,反转(a,5));
}
整数反转(整数a[],整数len){
合并排序(a,0,len-1);
返回计数;
}
无效合并排序(int a[],int左,int右){
if(左<右){
int mid=(左+右)/2;
合并排序(a、左、中);
合并排序(a,中间+1,右);
梅尔
#include <stdio.h>
#include <stdlib.h>
int _mergeSort(int arr[], int temp[], int left, int right);
int merge(int arr[], int temp[], int left, int mid, int right);
/* This function sorts the input array and returns the
number of inversions in the array */
int mergeSort(int arr[], int array_size)
{
int *temp = (int *)malloc(sizeof(int)*array_size);
return _mergeSort(arr, temp, 0, array_size - 1);
}
/* An auxiliary recursive function that sorts the input array and
returns the number of inversions in the array. */
int _mergeSort(int arr[], int temp[], int left, int right)
{
int mid, inv_count = 0;
if (right > left)
{
/* Divide the array into two parts and call _mergeSortAndCountInv()
for each of the parts */
mid = (right + left)/2;
/* Inversion count will be sum of inversions in left-part, right-part
and number of inversions in merging */
inv_count = _mergeSort(arr, temp, left, mid);
inv_count += _mergeSort(arr, temp, mid+1, right);
/*Merge the two parts*/
inv_count += merge(arr, temp, left, mid+1, right);
}
return inv_count;
}
/* This funt merges two sorted arrays and returns inversion count in
the arrays.*/
int merge(int arr[], int temp[], int left, int mid, int right)
{
int i, j, k;
int inv_count = 0;
i = left; /* i is index for left subarray*/
j = mid; /* i is index for right subarray*/
k = left; /* i is index for resultant merged subarray*/
while ((i <= mid - 1) && (j <= right))
{
if (arr[i] <= arr[j])
{
temp[k++] = arr[i++];
}
else
{
temp[k++] = arr[j++];
/*this is tricky -- see above explanation/diagram for merge()*/
inv_count = inv_count + (mid - i);
}
}
/* Copy the remaining elements of left subarray
(if there are any) to temp*/
while (i <= mid - 1)
temp[k++] = arr[i++];
/* Copy the remaining elements of right subarray
(if there are any) to temp*/
while (j <= right)
temp[k++] = arr[j++];
/*Copy back the merged elements to original array*/
for (i=left; i <= right; i++)
arr[i] = temp[i];
return inv_count;
}
/* Driver progra to test above functions */
int main(int argv, char** args)
{
int arr[] = {1, 20, 6, 4, 5};
printf(" Number of inversions are %d \n", mergeSort(arr, 5));
getchar();
return 0;
}
Node {
int data;
Node* left, *right;
int rightSubTreeSize;
Node(int data) {
rightSubTreeSize = 0;
}
};
Node* root = null;
int totCnt = 0;
for(i = 0; i < n; ++i) {
Node* p = new Node(a[i]);
if(root == null) {
root = p;
continue;
}
Node* q = root;
int curCnt = 0;
while(q) {
if(p->data <= q->data) {
curCnt += 1 + q->rightSubTreeSize;
if(q->left) {
q = q->left;
} else {
q->left = p;
break;
}
} else {
q->rightSubTreeSize++;
if(q->right) {
q = q->right;
} else {
q->right = p;
break;
}
}
}
totCnt += curCnt;
}
return totCnt;
public static int mergeSort(int[] a, int p, int r)
{
int countInversion = 0;
if(p < r)
{
int q = (p + r)/2;
countInversion = mergeSort(a, p, q);
countInversion += mergeSort(a, q+1, r);
countInversion += merge(a, p, q, r);
}
return countInversion;
}
public static int merge(int[] a, int p, int q, int r)
{
//p=0, q=1, r=3
int countingInversion = 0;
int n1 = q-p+1;
int n2 = r-q;
int[] temp1 = new int[n1+1];
int[] temp2 = new int[n2+1];
for(int i=0; i<n1; i++) temp1[i] = a[p+i];
for(int i=0; i<n2; i++) temp2[i] = a[q+1+i];
temp1[n1] = Integer.MAX_VALUE;
temp2[n2] = Integer.MAX_VALUE;
int i = 0, j = 0;
for(int k=p; k<=r; k++)
{
if(temp1[i] <= temp2[j])
{
a[k] = temp1[i];
i++;
}
else
{
a[k] = temp2[j];
j++;
countingInversion=countingInversion+(n1-i);
}
}
return countingInversion;
}
public static void main(String[] args)
{
int[] a = {1, 20, 6, 4, 5};
int countInversion = mergeSort(a, 0, a.length-1);
System.out.println(countInversion);
}
#include <algorithm>
vector<int> merge(vector<int>left, vector<int>right, int &counter)
{
vector<int> result;
vector<int>::iterator it_l=left.begin();
vector<int>::iterator it_r=right.begin();
int index_left=0;
while(it_l!=left.end() || it_r!=right.end())
{
// the following is true if we are finished with the left vector
// OR if the value in the right vector is the smaller one.
if(it_l==left.end() || (it_r!=right.end() && *it_r<*it_l) )
{
result.push_back(*it_r);
it_r++;
// increase inversion counter
counter+=left.size()-index_left;
}
else
{
result.push_back(*it_l);
it_l++;
index_left++;
}
}
return result;
}
vector<int> merge_sort_and_count(vector<int> A, int &counter)
{
int N=A.size();
if(N==1)return A;
vector<int> left(A.begin(),A.begin()+N/2);
vector<int> right(A.begin()+N/2,A.end());
left=merge_sort_and_count(left,counter);
right=merge_sort_and_count(right,counter);
return merge(left, right, counter);
}
inversionNumber <- function(x){
mergeSort <- function(x){
if(length(x) == 1){
inv <- 0
} else {
n <- length(x)
n1 <- ceiling(n/2)
n2 <- n-n1
y1 <- mergeSort(x[1:n1])
y2 <- mergeSort(x[n1+1:n2])
inv <- y1$inversions + y2$inversions
x1 <- y1$sortedVector
x2 <- y2$sortedVector
i1 <- 1
i2 <- 1
while(i1+i2 <= n1+n2+1){
if(i2 > n2 || i1 <= n1 && x1[i1] <= x2[i2]){
x[i1+i2-1] <- x1[i1]
i1 <- i1 + 1
} else {
inv <- inv + n1 + 1 - i1
x[i1+i2-1] <- x2[i2]
i2 <- i2 + 1
}
}
}
return (list(inversions=inv,sortedVector=x))
}
r <- mergeSort(x)
return (r$inversions)
}
import bisect
def solution(A):
sorted_left = []
res = 0
for i in xrange(1, len(A)):
bisect.insort_left(sorted_left, A[i-1])
# i is also the length of sorted_left
res += (i - bisect.bisect(sorted_left, A[i]))
return res
def count_inversions(a):
res = 0
counts = [0]*(len(a)+1)
rank = { v : i+1 for i, v in enumerate(sorted(a)) }
for x in reversed(a):
i = rank[x] - 1
while i:
res += counts[i]
i -= i & -i
i = rank[x]
while i <= len(a):
counts[i] += 1
i += i & -i
return res
public class FindInversions {
public static int solution(int[] input) {
if (input == null)
return 0;
int[] helper = new int[input.length];
return mergeSort(0, input.length - 1, input, helper);
}
public static int mergeSort(int low, int high, int[] input, int[] helper) {
int inversionCount = 0;
if (low < high) {
int medium = low + (high - low) / 2;
inversionCount += mergeSort(low, medium, input, helper);
inversionCount += mergeSort(medium + 1, high, input, helper);
inversionCount += merge(low, medium, high, input, helper);
}
return inversionCount;
}
public static int merge(int low, int medium, int high, int[] input, int[] helper) {
int inversionCount = 0;
for (int i = low; i <= high; i++)
helper[i] = input[i];
int i = low;
int j = medium + 1;
int k = low;
while (i <= medium && j <= high) {
if (helper[i] <= helper[j]) {
input[k] = helper[i];
i++;
} else {
input[k] = helper[j];
// the number of elements in the first half which the j element needs to jump over.
// there is an inversion between each of those elements and j.
inversionCount += (medium + 1 - i);
j++;
}
k++;
}
// finish writing back in the input the elements from the first part
while (i <= medium) {
input[k] = helper[i];
i++;
k++;
}
return inversionCount;
}
}
def solution(t)
sorted, inversion_count = sort_inversion_count(t)
return inversion_count
end
def sort_inversion_count(t)
midpoint = t.length / 2
left_half = t[0...midpoint]
right_half = t[midpoint..t.length]
if midpoint == 0
return t, 0
end
sorted_left_half, left_half_inversion_count = sort_inversion_count(left_half)
sorted_right_half, right_half_inversion_count = sort_inversion_count(right_half)
sorted = []
inversion_count = 0
while sorted_left_half.length > 0 or sorted_right_half.length > 0
if sorted_left_half.empty?
sorted.push sorted_right_half.shift
elsif sorted_right_half.empty?
sorted.push sorted_left_half.shift
else
if sorted_left_half[0] > sorted_right_half[0]
inversion_count += sorted_left_half.length
sorted.push sorted_right_half.shift
else
sorted.push sorted_left_half.shift
end
end
end
return sorted, inversion_count + left_half_inversion_count + right_half_inversion_count
end
require "minitest/autorun"
class TestCodility < Minitest::Test
def test_given_example
a = [-1, 6, 3, 4, 7, 4]
assert_equal solution(a), 4
end
def test_empty
a = []
assert_equal solution(a), 0
end
def test_singleton
a = [0]
assert_equal solution(a), 0
end
def test_none
a = [1,2,3,4,5,6,7]
assert_equal solution(a), 0
end
def test_all
a = [5,4,3,2,1]
assert_equal solution(a), 10
end
def test_clones
a = [4,4,4,4,4,4]
assert_equal solution(a), 0
end
end
/**
*array sorting needed to verify if first arrays n'th element is greater than sencond arrays
*some element then all elements following n will do the same
*/
#include<stdio.h>
#include<iostream>
using namespace std;
int countInversions(int array[],int size);
int merge(int arr1[],int size1,int arr2[],int size2,int[]);
int main()
{
int array[] = {2, 4, 1, 3, 5};
int size = sizeof(array) / sizeof(array[0]);
int x = countInversions(array,size);
printf("number of inversions = %d",x);
}
int countInversions(int array[],int size)
{
if(size > 1 )
{
int mid = size / 2;
int count1 = countInversions(array,mid);
int count2 = countInversions(array+mid,size-mid);
int temp[size];
int count3 = merge(array,mid,array+mid,size-mid,temp);
for(int x =0;x<size ;x++)
{
array[x] = temp[x];
}
return count1 + count2 + count3;
}else{
return 0;
}
}
int merge(int arr1[],int size1,int arr2[],int size2,int temp[])
{
int count = 0;
int a = 0;
int b = 0;
int c = 0;
while(a < size1 && b < size2)
{
if(arr1[a] < arr2[b])
{
temp[c] = arr1[a];
c++;
a++;
}else{
temp[c] = arr2[b];
b++;
c++;
count = count + size1 -a;
}
}
while(a < size1)
{
temp[c] = arr1[a];
c++;a++;
}
while(b < size2)
{
temp[c] = arr2[b];
c++;b++;
}
return count;
}
sub sort_and_count {
my ($arr, $n) = @_;
return ($arr, 0) unless $n > 1;
my $mid = $n % 2 == 1 ? ($n-1)/2 : $n/2;
my @left = @$arr[0..$mid-1];
my @right = @$arr[$mid..$n-1];
my ($sleft, $x) = sort_and_count( \@left, $mid );
my ($sright, $y) = sort_and_count( \@right, $n-$mid);
my ($merged, $z) = merge_and_countsplitinv( $sleft, $sright, $n );
return ($merged, $x+$y+$z);
}
sub merge_and_countsplitinv {
my ($left, $right, $n) = @_;
my ($l_c, $r_c) = ($#$left+1, $#$right+1);
my ($i, $j) = (0, 0);
my @merged;
my $inv = 0;
for my $k (0..$n-1) {
if ($i<$l_c && $j<$r_c) {
if ( $left->[$i] < $right->[$j]) {
push @merged, $left->[$i];
$i+=1;
} else {
push @merged, $right->[$j];
$j+=1;
$inv += $l_c - $i;
}
} else {
if ($i>=$l_c) {
push @merged, @$right[ $j..$#$right ];
} else {
push @merged, @$left[ $i..$#$left ];
}
last;
}
}
return (\@merged, $inv);
}
def merge(l1,l2):
l = []
# global count
while l1 and l2:
if l1[-1] <= l2[-1]:
l.append(l2.pop())
else:
l.append(l1.pop())
# count += len(l2)
l.reverse()
return l1 + l2 + l
def sort(l):
t = len(l) // 2
return merge(sort(l[:t]), sort(l[t:])) if t > 0 else l
count=0
print(sort([5,1,2,4,9,3]), count)
# [1, 2, 3, 4, 5, 9] 6
def part(l):
pivot=l[-1]
small,big = [],[]
count = big_count = 0
for x in l:
if x <= pivot:
small.append(x)
count += big_count
else:
big.append(x)
big_count += 1
return count,small,big
def quick_count(l):
if len(l)<2 : return 0
count,small,big = part(l)
small.pop()
return count + quick_count(small) + quick_count(big)
def count_inversions(a):
n = a.size
counts = np.arange(n) & -np.arange(n) # The BIT
ags = a.argsort(kind='mergesort')
return BIT(ags,counts,n)
@numba.njit
def BIT(ags,counts,n):
res = 0
for x in ags :
i = x
while i:
res += counts[i]
i -= i & -i
i = x+1
while i < n:
counts[i] -= 1
i += i & -i
return res
def binarySearch(alist, item):
first = 0
last = len(alist) - 1
found = False
while first <= last and not found:
midpoint = (first + last)//2
if alist[midpoint] == item:
return midpoint
else:
if item < alist[midpoint]:
last = midpoint - 1
else:
first = midpoint + 1
def solution(A):
B = list(A)
B.sort()
inversion_count = 0
for i in range(len(A)):
j = binarySearch(B, A[i])
while B[j] == B[j - 1]:
if j < 1:
break
j -= 1
inversion_count += j
B.pop(j)
if inversion_count > 1000000000:
return -1
else:
return inversion_count
print solution([4, 10, 11, 1, 3, 9, 10])
//Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i,n;
cin >> n;
int arr[n],inv[n];
for(i=0;i<n;i++){
cin >> arr[i];
}
vector<int> v;
v.push_back(arr[n-1]);
inv[n-1]=0;
for(i=n-2;i>=0;i--){
auto it = lower_bound(v.begin(),v.end(),arr[i]);
//calculating least element in vector v which is greater than arr[i]
inv[i]=it-v.begin();
//calculating distance from starting of vector
v.insert(it,arr[i]);
//inserting that element into vector v
}
for(i=0;i<n;i++){
cout << inv[i] << " ";
}
cout << endl;
return 0;
}
//INPUT
4
2 1 4 3
//OUTPUT
1 0 1 0
//To calculate total inversion count just add up all the elements in output array
public class TestInversionThruMergeSort {
static int count =0;
public static void main(String[] args) {
int[] arr = {6, 9, 1, 14, 8, 12, 3, 2};
partition(arr);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.println("inversions are "+count);
}
public static void partition(int[] arr) {
if (arr.length > 1) {
int mid = (arr.length) / 2;
int[] left = null;
if (mid > 0) {
left = new int[mid];
for (int i = 0; i < mid; i++) {
left[i] = arr[i];
}
}
int[] right = new int[arr.length - left.length];
if ((arr.length - left.length) > 0) {
int j = 0;
for (int i = mid; i < arr.length; i++) {
right[j] = arr[i];
++j;
}
}
partition(left);
partition(right);
mergeToParent(left, right, arr);
}
}
public static void mergeToParent(int[] left, int[] right, int[] parent) {
int leftunPicked = 0;
int rightunPicked = 0;
int parentIndex = -1;
while (rightunPicked < right.length && leftunPicked < left.length) {
if (left[leftunPicked] < right[rightunPicked]) {
parent[++parentIndex] = left[leftunPicked];
++leftunPicked;
} else {
count = count + left.length-leftunPicked;
if ((rightunPicked < right.length)) {
parent[++parentIndex] = right[rightunPicked];
++rightunPicked;
}
}
}
while (leftunPicked < left.length) {
parent[++parentIndex] = left[leftunPicked];
++leftunPicked;
}
while (rightunPicked < right.length) {
parent[++parentIndex] = right[rightunPicked];
++rightunPicked;
}
}
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class TestInversion {
public static void main(String[] args) {
Integer [] arr1 = {6, 9, 1, 14, 8, 12, 3, 2};
List<Integer> arr = new ArrayList(Arrays.asList(arr1));
List<Integer> sortArr = new ArrayList<Integer>();
for(int i=0;i<arr.size();i++){
sortArr.add(arr.get(i));
}
Collections.sort(sortArr);
int inversion = 0;
Iterator<Integer> iter = arr.iterator();
while(iter.hasNext()){
Integer el = (Integer)iter.next();
int index = sortArr.indexOf(el);
if(index+1 > 1){
inversion = inversion + ((index+1)-1);
}
//iter.remove();
sortArr.remove(el);
}
System.out.println("Inversions are "+inversion);
}
}
maxPossibleInversions = (n * (n-1) ) / 2
var arr = [6,5,4,3,2,1]; // Sample input array
var inversionCount = 0;
function mergeSort(arr) {
if(arr.length == 1)
return arr;
if(arr.length > 1) {
let breakpoint = Math.ceil((arr.length/2));
// Left list starts with 0, breakpoint-1
let leftList = arr.slice(0,breakpoint);
// Right list starts with breakpoint, length-1
let rightList = arr.slice(breakpoint,arr.length);
// Make a recursive call
leftList = mergeSort(leftList);
rightList = mergeSort(rightList);
var a = merge(leftList,rightList);
return a;
}
}
function merge(leftList,rightList) {
let result = [];
while(leftList.length && rightList.length) {
/**
* The shift() method removes the first element from an array
* and returns that element. This method changes the length
* of the array.
*/
if(leftList[0] <= rightList[0]) {
result.push(leftList.shift());
}else{
inversionCount += leftList.length;
result.push(rightList.shift());
}
}
while(leftList.length)
result.push(leftList.shift());
while(rightList.length)
result.push(rightList.shift());
console.log(result);
return result;
}
mergeSort(arr);
console.log('Number of inversions: ' + inversionCount);
nSwaps += mid + 1 - iL
def count_inversions(a):
total = 0
counts = [0] * len(a)
rank = {v: i for i, v in enumerate(sorted(a))}
for u in reversed(a):
i = rank[u]
total += sum(counts[:i])
counts[i] += 1
return total
seq = [15, 14, 11, 12, 10, 13]
b = [t[::-1] for t in enumerate(seq)]
print(b)
b.sort()
print(b)
[(15, 0), (14, 1), (11, 2), (12, 3), (10, 4), (13, 5)]
[(10, 4), (11, 2), (12, 3), (13, 5), (14, 1), (15, 0)]
print(sorted(range(len(seq)), key=lambda k: seq[k]))
[4, 2, 3, 5, 1, 0]
sorted(range(len(seq)), key=seq.__getitem__)
count_inversions speed test results
Size = 5, hi = 2, 4096 loops
ltree_count_PM2R : 0.04871, 0.04872, 0.04876
bruteforce_loops_PM2R : 0.05696, 0.05700, 0.05776
solution_TimBabych : 0.05760, 0.05822, 0.05943
solutionE_TimBabych : 0.06642, 0.06704, 0.06760
bruteforce_sum_PM2R : 0.07523, 0.07545, 0.07563
perm_sum_PM2R : 0.09873, 0.09875, 0.09935
rank_sum_PM2R : 0.10449, 0.10463, 0.10468
solution_python : 0.13034, 0.13061, 0.13221
fenwick_inline_PM2R : 0.14323, 0.14610, 0.18802
perm_radixR_PM2R : 0.15146, 0.15203, 0.15235
merge_count_BM : 0.16179, 0.16267, 0.16467
perm_radixI_PM2R : 0.16200, 0.16202, 0.16768
perm_fenwick_PM2R : 0.16887, 0.16920, 0.17075
merge_PM2R : 0.18262, 0.18271, 0.18418
count_inversions_NiklasB : 0.19183, 0.19279, 0.20388
count_inversion_mkso : 0.20060, 0.20141, 0.20398
inv_cnt_ZheHu : 0.20815, 0.20841, 0.20906
fenwick_PM2R : 0.22109, 0.22137, 0.22379
reversePairs_nomanpouigt : 0.29620, 0.29689, 0.30293
Value: 5
Size = 10, hi = 5, 2048 loops
solution_TimBabych : 0.05954, 0.05989, 0.05991
solutionE_TimBabych : 0.05970, 0.05972, 0.05998
perm_sum_PM2R : 0.07517, 0.07519, 0.07520
ltree_count_PM2R : 0.07672, 0.07677, 0.07684
bruteforce_loops_PM2R : 0.07719, 0.07724, 0.07817
rank_sum_PM2R : 0.08587, 0.08823, 0.08864
bruteforce_sum_PM2R : 0.09470, 0.09472, 0.09484
solution_python : 0.13126, 0.13154, 0.13185
perm_radixR_PM2R : 0.14239, 0.14320, 0.14474
perm_radixI_PM2R : 0.14632, 0.14669, 0.14679
fenwick_inline_PM2R : 0.16796, 0.16831, 0.17030
perm_fenwick_PM2R : 0.18189, 0.18212, 0.18638
merge_count_BM : 0.19816, 0.19870, 0.19948
count_inversions_NiklasB : 0.21807, 0.22031, 0.22215
merge_PM2R : 0.22037, 0.22048, 0.26106
fenwick_PM2R : 0.24290, 0.24314, 0.24744
count_inversion_mkso : 0.24895, 0.24899, 0.25205
inv_cnt_ZheHu : 0.26253, 0.26259, 0.26590
reversePairs_nomanpouigt : 0.35711, 0.35762, 0.35973
Value: 20
Size = 20, hi = 10, 1024 loops
solutionE_TimBabych : 0.05687, 0.05696, 0.05720
solution_TimBabych : 0.06126, 0.06151, 0.06168
perm_sum_PM2R : 0.06875, 0.06906, 0.07054
rank_sum_PM2R : 0.07988, 0.07995, 0.08002
ltree_count_PM2R : 0.11232, 0.11239, 0.11257
bruteforce_loops_PM2R : 0.12553, 0.12584, 0.12592
solution_python : 0.13472, 0.13540, 0.13694
bruteforce_sum_PM2R : 0.15820, 0.15849, 0.16021
perm_radixI_PM2R : 0.17101, 0.17148, 0.17229
perm_radixR_PM2R : 0.17891, 0.18087, 0.18366
perm_fenwick_PM2R : 0.20554, 0.20708, 0.21412
fenwick_inline_PM2R : 0.21161, 0.21163, 0.22047
merge_count_BM : 0.24125, 0.24261, 0.24565
count_inversions_NiklasB : 0.25712, 0.25754, 0.25778
merge_PM2R : 0.26477, 0.26566, 0.31297
fenwick_PM2R : 0.28178, 0.28216, 0.29069
count_inversion_mkso : 0.30286, 0.30290, 0.30652
inv_cnt_ZheHu : 0.32024, 0.32041, 0.32447
reversePairs_nomanpouigt : 0.45812, 0.45822, 0.46172
Value: 98
Size = 40, hi = 20, 512 loops
solutionE_TimBabych : 0.05784, 0.05787, 0.05958
solution_TimBabych : 0.06452, 0.06475, 0.06479
perm_sum_PM2R : 0.07254, 0.07261, 0.07263
rank_sum_PM2R : 0.08537, 0.08540, 0.08572
ltree_count_PM2R : 0.11744, 0.11749, 0.11792
solution_python : 0.14262, 0.14285, 0.14465
perm_radixI_PM2R : 0.18774, 0.18776, 0.18922
perm_radixR_PM2R : 0.19425, 0.19435, 0.19609
bruteforce_loops_PM2R : 0.21500, 0.21511, 0.21686
perm_fenwick_PM2R : 0.23338, 0.23375, 0.23674
fenwick_inline_PM2R : 0.24947, 0.24958, 0.25189
bruteforce_sum_PM2R : 0.27627, 0.27646, 0.28041
merge_count_BM : 0.28059, 0.28128, 0.28294
count_inversions_NiklasB : 0.28557, 0.28759, 0.29022
merge_PM2R : 0.29886, 0.29928, 0.30317
fenwick_PM2R : 0.30241, 0.30259, 0.35237
count_inversion_mkso : 0.34252, 0.34356, 0.34441
inv_cnt_ZheHu : 0.37468, 0.37569, 0.37847
reversePairs_nomanpouigt : 0.50725, 0.50770, 0.50943
Value: 369
Size = 80, hi = 40, 256 loops
solutionE_TimBabych : 0.06339, 0.06373, 0.06513
solution_TimBabych : 0.06984, 0.06994, 0.07009
perm_sum_PM2R : 0.09171, 0.09172, 0.09186
rank_sum_PM2R : 0.10468, 0.10474, 0.10500
ltree_count_PM2R : 0.14416, 0.15187, 0.18541
solution_python : 0.17415, 0.17423, 0.17451
perm_radixI_PM2R : 0.20676, 0.20681, 0.20936
perm_radixR_PM2R : 0.21671, 0.21695, 0.21736
perm_fenwick_PM2R : 0.26197, 0.26252, 0.26264
fenwick_inline_PM2R : 0.28111, 0.28249, 0.28382
count_inversions_NiklasB : 0.31746, 0.32448, 0.32451
merge_count_BM : 0.31964, 0.33842, 0.35276
merge_PM2R : 0.32890, 0.32941, 0.33322
fenwick_PM2R : 0.34355, 0.34377, 0.34873
count_inversion_mkso : 0.37689, 0.37698, 0.38079
inv_cnt_ZheHu : 0.42923, 0.42941, 0.43249
bruteforce_loops_PM2R : 0.43544, 0.43601, 0.43902
bruteforce_sum_PM2R : 0.52106, 0.52160, 0.52531
reversePairs_nomanpouigt : 0.57805, 0.58156, 0.58252
Value: 1467
Size = 160, hi = 80, 128 loops
solutionE_TimBabych : 0.06766, 0.06784, 0.06963
solution_TimBabych : 0.07433, 0.07489, 0.07516
perm_sum_PM2R : 0.13143, 0.13175, 0.13179
rank_sum_PM2R : 0.14428, 0.14440, 0.14922
solution_python : 0.20072, 0.20076, 0.20084
ltree_count_PM2R : 0.20314, 0.20583, 0.24776
perm_radixI_PM2R : 0.23061, 0.23078, 0.23525
perm_radixR_PM2R : 0.23894, 0.23915, 0.24234
perm_fenwick_PM2R : 0.30984, 0.31181, 0.31503
fenwick_inline_PM2R : 0.31933, 0.32680, 0.32722
merge_count_BM : 0.36003, 0.36387, 0.36409
count_inversions_NiklasB : 0.36796, 0.36814, 0.37106
merge_PM2R : 0.36847, 0.36848, 0.37127
fenwick_PM2R : 0.37833, 0.37847, 0.38095
count_inversion_mkso : 0.42746, 0.42747, 0.43184
inv_cnt_ZheHu : 0.48969, 0.48974, 0.49293
reversePairs_nomanpouigt : 0.67791, 0.68157, 0.72420
bruteforce_loops_PM2R : 0.82816, 0.83175, 0.83282
bruteforce_sum_PM2R : 1.03322, 1.03378, 1.03562
Value: 6194
Size = 320, hi = 160, 64 loops
solutionE_TimBabych : 0.07467, 0.07470, 0.07483
solution_TimBabych : 0.08036, 0.08066, 0.08077
perm_sum_PM2R : 0.21142, 0.21201, 0.25766
solution_python : 0.22410, 0.22644, 0.22897
rank_sum_PM2R : 0.22820, 0.22851, 0.22877
ltree_count_PM2R : 0.24424, 0.24595, 0.24645
perm_radixI_PM2R : 0.25690, 0.25710, 0.26191
perm_radixR_PM2R : 0.26501, 0.26504, 0.26729
perm_fenwick_PM2R : 0.33483, 0.33507, 0.33845
fenwick_inline_PM2R : 0.34413, 0.34484, 0.35153
merge_count_BM : 0.39875, 0.39919, 0.40302
fenwick_PM2R : 0.40434, 0.40439, 0.40845
merge_PM2R : 0.40814, 0.41531, 0.51417
count_inversions_NiklasB : 0.41681, 0.42009, 0.42128
count_inversion_mkso : 0.47132, 0.47192, 0.47385
inv_cnt_ZheHu : 0.54468, 0.54750, 0.54893
reversePairs_nomanpouigt : 0.76164, 0.76389, 0.80357
bruteforce_loops_PM2R : 1.59125, 1.60430, 1.64131
bruteforce_sum_PM2R : 2.03734, 2.03834, 2.03975
Value: 24959
Run 2
Size = 640, hi = 320, 8 loops
solutionE_TimBabych : 0.04135, 0.04374, 0.04575
ltree_count_PM2R : 0.06738, 0.06758, 0.06874
perm_radixI_PM2R : 0.06928, 0.06943, 0.07019
fenwick_inline_PM2R : 0.07850, 0.07856, 0.08059
perm_fenwick_PM2R : 0.08151, 0.08162, 0.08170
perm_sum_PM2R : 0.09122, 0.09133, 0.09221
rank_sum_PM2R : 0.09549, 0.09603, 0.11270
merge_count_BM : 0.10733, 0.10807, 0.11032
count_inversions_NiklasB : 0.12460, 0.19865, 0.20205
solution_python : 0.13514, 0.13585, 0.13814
Size = 1280, hi = 640, 8 loops
solutionE_TimBabych : 0.04714, 0.04742, 0.04752
perm_radixI_PM2R : 0.15325, 0.15388, 0.15525
solution_python : 0.15709, 0.15715, 0.16076
fenwick_inline_PM2R : 0.16048, 0.16160, 0.16403
ltree_count_PM2R : 0.16213, 0.16238, 0.16428
perm_fenwick_PM2R : 0.16408, 0.16416, 0.16449
count_inversions_NiklasB : 0.19755, 0.19833, 0.19897
merge_count_BM : 0.23736, 0.23793, 0.23912
perm_sum_PM2R : 0.32946, 0.32969, 0.33277
rank_sum_PM2R : 0.34637, 0.34756, 0.34858
Size = 2560, hi = 1280, 8 loops
solutionE_TimBabych : 0.10898, 0.11005, 0.11025
perm_radixI_PM2R : 0.33345, 0.33352, 0.37656
ltree_count_PM2R : 0.34670, 0.34786, 0.34833
perm_fenwick_PM2R : 0.34816, 0.34879, 0.35214
fenwick_inline_PM2R : 0.36196, 0.36455, 0.36741
solution_python : 0.36498, 0.36637, 0.40887
count_inversions_NiklasB : 0.42274, 0.42745, 0.42995
merge_count_BM : 0.50799, 0.50898, 0.50917
perm_sum_PM2R : 1.27773, 1.27897, 1.27951
rank_sum_PM2R : 1.29728, 1.30389, 1.30448
Size = 5120, hi = 2560, 8 loops
solutionE_TimBabych : 0.26914, 0.26993, 0.27253
perm_radixI_PM2R : 0.71416, 0.71634, 0.71753
perm_fenwick_PM2R : 0.71976, 0.72078, 0.72078
fenwick_inline_PM2R : 0.72776, 0.72804, 0.73143
ltree_count_PM2R : 0.81972, 0.82043, 0.82290
solution_python : 0.83714, 0.83756, 0.83962
count_inversions_NiklasB : 0.87282, 0.87395, 0.92087
merge_count_BM : 1.09496, 1.09584, 1.10207
rank_sum_PM2R : 5.02564, 5.06277, 5.06666
perm_sum_PM2R : 5.09088, 5.12999, 5.13512
Size = 10240, hi = 5120, 8 loops
solutionE_TimBabych : 0.71556, 0.71718, 0.72201
perm_radixI_PM2R : 1.54785, 1.55096, 1.55515
perm_fenwick_PM2R : 1.55103, 1.55353, 1.59298
fenwick_inline_PM2R : 1.57118, 1.57240, 1.57271
ltree_count_PM2R : 1.76240, 1.76247, 1.80944
count_inversions_NiklasB : 1.86543, 1.86851, 1.87208
solution_python : 2.01490, 2.01519, 2.06423
merge_count_BM : 2.35215, 2.35301, 2.40023
rank_sum_PM2R : 20.07048, 20.08399, 20.13200
perm_sum_PM2R : 20.10187, 20.12551, 20.12683
Run 3
Size = 20480, hi = 10240, 4 loops
solutionE_TimBabych : 1.07636, 1.08243, 1.09569
perm_radixI_PM2R : 1.59579, 1.60519, 1.61785
perm_fenwick_PM2R : 1.66885, 1.68549, 1.71109
fenwick_inline_PM2R : 1.72073, 1.72752, 1.77217
ltree_count_PM2R : 1.96900, 1.97820, 2.02578
count_inversions_NiklasB : 2.03257, 2.05005, 2.18548
merge_count_BM : 2.46768, 2.47377, 2.52133
solution_python : 2.49833, 2.50179, 3.79819
Size = 40960, hi = 20480, 4 loops
solutionE_TimBabych : 3.51733, 3.52008, 3.56996
perm_radixI_PM2R : 3.51736, 3.52365, 3.56459
perm_fenwick_PM2R : 3.76097, 3.80900, 3.87974
fenwick_inline_PM2R : 3.95099, 3.96300, 3.99748
ltree_count_PM2R : 4.49866, 4.54652, 5.39716
count_inversions_NiklasB : 4.61851, 4.64303, 4.73026
merge_count_BM : 5.31945, 5.35378, 5.35951
solution_python : 6.78756, 6.82911, 6.98217
Size = 81920, hi = 40960, 4 loops
perm_radixI_PM2R : 7.68723, 7.71986, 7.72135
perm_fenwick_PM2R : 8.52404, 8.53349, 8.53710
fenwick_inline_PM2R : 8.97082, 8.97561, 8.98347
ltree_count_PM2R : 10.01142, 10.01426, 10.03216
count_inversions_NiklasB : 10.60807, 10.62424, 10.70425
merge_count_BM : 11.42149, 11.42342, 11.47003
solutionE_TimBabych : 12.83390, 12.83485, 12.89747
solution_python : 19.66092, 19.67067, 20.72204
Size = 163840, hi = 81920, 4 loops
perm_radixI_PM2R : 17.14153, 17.16885, 17.22240
perm_fenwick_PM2R : 19.25944, 19.27844, 20.27568
fenwick_inline_PM2R : 19.78221, 19.80219, 19.80766
ltree_count_PM2R : 22.42240, 22.43259, 22.48837
count_inversions_NiklasB : 22.97341, 23.01516, 23.98052
merge_count_BM : 24.42683, 24.48559, 24.51488
solutionE_TimBabych : 60.96006, 61.20145, 63.71835
solution_python : 73.75132, 73.79854, 73.95874
Size = 327680, hi = 163840, 4 loops
perm_radixI_PM2R : 36.56715, 36.60221, 37.05071
perm_fenwick_PM2R : 42.21616, 42.21838, 42.26053
fenwick_inline_PM2R : 43.04987, 43.09075, 43.13287
ltree_count_PM2R : 49.87400, 50.08509, 50.69292
count_inversions_NiklasB : 50.74591, 50.75012, 50.75551
merge_count_BM : 52.37284, 52.51491, 53.43003
solutionE_TimBabych : 373.67198, 377.03341, 377.42360
solution_python : 411.69178, 411.92691, 412.83856
Size = 655360, hi = 327680, 4 loops
perm_radixI_PM2R : 78.51927, 78.66327, 79.46325
perm_fenwick_PM2R : 90.64711, 90.80328, 91.76126
fenwick_inline_PM2R : 93.32482, 93.39086, 94.28880
count_inversions_NiklasB : 107.74393, 107.80036, 108.71443
ltree_count_PM2R : 109.11328, 109.23592, 110.18247
merge_count_BM : 111.05633, 111.07840, 112.05861
solutionE_TimBabych : 1830.46443, 1836.39960, 1849.53918
solution_python : 1911.03692, 1912.04484, 1914.69786
int merge(vector<int>&nums , int low , int mid , int high){
int size1 = mid - low +1;
int size2= high - mid;
vector<int>left;
vector<int>right;
for(int i = 0 ; i < size1 ; ++i){
left.push_back(nums[low+i]);
}
for(int i = 0 ; i <size2 ; ++i){
right.push_back(nums[mid+i+1]);
}
left.push_back(INT_MAX);
right.push_back(INT_MAX);
int i = 0 ;
int j = 0;
int start = low;
int inversion = 0 ;
while(i < size1 && j < size2){
if(left[i]<right[j]){
nums[start] = left[i];
start++;
i++;
}else{
for(int l = i ; l < size1; ++l){
cout<<"("<<left[l]<<","<<right[j]<<")"<<endl;
}
inversion += size1 - i;
nums[start] = right[j];
start++;
j++;
}
}
if(i == size1){
for(int c = j ; c< size2 ; ++c){
nums[start] = right[c];
start++;
}
}
if(j == size2){
for(int c = i ; c< size1 ; ++c){
nums[start] = left[c];
start++;
}
}
return inversion;
}
int inversion_count(vector<int>& nums , int low , int high){
if(high>low){
int mid = low + (high-low)/2;
int left = inversion_count(nums,low,mid);
int right = inversion_count(nums,mid+1,high);
int inversion = merge(nums,low,mid,high) + left + right;
return inversion;
}
return 0 ;
}
def countInversions(arr):
n = len(arr)
if n == 1:
return 0
n1 = n // 2
n2 = n - n1
arr1 = arr[:n1]
arr2 = arr[n1:]
# print(n1,'||',n1,'||',arr1,'||',arr2)
ans = countInversions(arr1) + countInversions(arr2)
print(ans)
i1 = 0
i2 = 0
for i in range(n):
# print(i1,n1,i2,n2)
if i1 < n1 and (i2 >= n2 or arr1[i1] <= arr2[i2]):
arr[i] = arr1[i1]
ans += i2
i1 += 1
elif i2 < n2:
arr[i] = arr2[i2]
i2 += 1
return ans
def countInversions(arr):
count = 0
for i in range(len(arr)):
for j in range(i, len(arr)):
# print(arr[i:len(arr)])
if arr[i] > arr[j]:
print(arr[i], arr[j])
count += 1
print(count)