## Friday, December 18, 2015

### Count inversions in an array

http://www.geeksforgeeks.org/count-inversions-in-an-array-set-2-using-self-balancing-bst/
Time Complexity of the Naive approach is O(n2) and that of merge sort based approach is O(n Log n). In this post one more O(n Log n) approach is discussed. The idea is to use Self-Balancing Binary Search Tree like Red-Black TreeAVL Tree, etc and augment it so that every node also keeps track of number of nodes in right subtree.
```1) Create an empty AVL Tree.  The tree is augmented here
such that every node also maintains size of subtree
rooted with this node.

2) Initialize inversion count or result as 0.

3) Iterate from 0 to n-1 and do following for every
element in arr[i]
a) Insert arr[i] into the AVL Tree.  The insertion
operation also updates result.  The idea is to
keep counting greater nodes when tree is traversed
from root to a leaf for insertion.

4) Return result. ```
More explanation for step 3.a:
1) When we insert arr[i], elements from arr[0] to arr[i-1] are already inserted into AVL Tree. All we need to do is count these nodes.
2) For insertion into AVL Tree, we traverse tree from root to a leaf by comparing every node with arr[i[]. When arr[i[ is smaller than current node, we increase inversion count by 1 plus the number of nodes in right subtree of current node. Which is basically count of greater elements on left of arr[i], i.e., inversions.
`// An AVL tree node`
`struct` `Node`
`{`
`    ``int` `key, height;`
`    ``struct` `Node *left, *right;`
`    ``int` `size; ``// size of the tree rooted with this Node`
`};`
`// A utility function to get height of the tree rooted with N`
`int` `height(``struct` `Node *N)`
`{`
`    ``if` `(N == NULL)`
`        ``return` `0;`
`    ``return` `N->height;`
`}`
`// A utility function to size of the tree of rooted with N`
`int` `size(``struct` `Node *N)`
`{`
`    ``if` `(N == NULL)`
`        ``return` `0;`
`    ``return` `N->size;`
`}`
`/* Helper function that allocates a new Node with the given key and`
`    ``NULL left and right pointers. */`
`struct` `Node* newNode(``int` `key)`
`{`
`    ``struct` `Node* node = ``new` `Node;`
`    ``node->key   = key;`
`    ``node->left   = node->right  = NULL;`
`    ``node->height = node->size = 1;`
`    ``return``(node);`
`}`
`// A utility function to right rotate subtree rooted with y`
`struct` `Node *rightRotate(``struct` `Node *y)`
`{`
`    ``struct` `Node *x = y->left;`
`    ``struct` `Node *T2 = x->right;`
`    ``// Perform rotation`
`    ``x->right = y;`
`    ``y->left = T2;`
`    ``// Update heights`
`    ``y->height = max(height(y->left), height(y->right))+1;`
`    ``x->height = max(height(x->left), height(x->right))+1;`
`    ``// Update sizes`
`    ``y->size = size(y->left) + size(y->right) + 1;`
`    ``x->size = size(x->left) + size(x->right) + 1;`
`    ``// Return new root`
`    ``return` `x;`
`}`
`// A utility function to left rotate subtree rooted with x`
`struct` `Node *leftRotate(``struct` `Node *x)`
`{`
`    ``struct` `Node *y = x->right;`
`    ``struct` `Node *T2 = y->left;`
`    ``// Perform rotation`
`    ``y->left = x;`
`    ``x->right = T2;`
`    ``//  Update heights`
`    ``x->height = max(height(x->left), height(x->right))+1;`
`    ``y->height = max(height(y->left), height(y->right))+1;`
`    ``// Update sizes`
`    ``x->size = size(x->left) + size(x->right) + 1;`
`    ``y->size = size(y->left) + size(y->right) + 1;`
`    ``// Return new root`
`    ``return` `y;`
`}`
`// Get Balance factor of Node N`
`int` `getBalance(``struct` `Node *N)`
`{`
`    ``if` `(N == NULL)`
`        ``return` `0;`
`    ``return` `height(N->left) - height(N->right);`
`}`
`// Inserts a new key to the tree rotted with Node. Also, updates`
`// *result (inversion count)`
`struct` `Node* insert(``struct` `Node* node, ``int` `key, ``int` `*result)`
`{`
`    ``/* 1.  Perform the normal BST rotation */`
`    ``if` `(node == NULL)`
`        ``return``(newNode(key));`
`    ``if` `(key < node->key)`
`    ``{`
`        ``node->left  = insert(node->left, key, result);`
`        ``// UPDATE COUNT OF GREATE ELEMENTS FOR KEY`
`        ``*result = *result + size(node->right) + 1;`
`    ``}`
`    ``else`
`        ``node->right = insert(node->right, key, result);`
`    ``/* 2. Update height and size of this ancestor node */`
`    ``node->height = max(height(node->left),`
`                       ``height(node->right)) + 1;`
`    ``node->size = size(node->left) + size(node->right) + 1;`
`    ``/* 3. Get the balance factor of this ancestor node to`
`          ``check whether this node became unbalanced */`
`    ``int` `balance = getBalance(node);`
`    ``// If this node becomes unbalanced, then there are`
`    ``// 4 cases`
`    ``// Left Left Case`
`    ``if` `(balance > 1 && key < node->left->key)`
`        ``return` `rightRotate(node);`
`    ``// Right Right Case`
`    ``if` `(balance < -1 && key > node->right->key)`
`        ``return` `leftRotate(node);`
`    ``// Left Right Case`
`    ``if` `(balance > 1 && key > node->left->key)`
`    ``{`
`        ``node->left =  leftRotate(node->left);`
`        ``return` `rightRotate(node);`
`    ``}`
`    ``// Right Left Case`
`    ``if` `(balance < -1 && key < node->right->key)`
`    ``{`
`        ``node->right = rightRotate(node->right);`
`        ``return` `leftRotate(node);`
`    ``}`
`    ``/* return the (unchanged) node pointer */`
`    ``return` `node;`
`}`
`// The following function returns inversion count in arr[]`
`int` `getInvCount(``int` `arr[], ``int` `n)`
`{`
`  ``struct` `Node *root = NULL;  ``// Create empty AVL Tree`
`  ``int` `result = 0;   ``// Initialize result`
`  ``// Starting from first element, insert all elements one by`
`  ``// one in an AVL tree.`
`  ``for` `(``int` `i=0; i<n; i++)`
`     ``// Note that address of result is passed as insert`
`     ``// operation updates result by adding count of elements`
`     ``// greater than arr[i] on left of arr[i]`
`     ``root = insert(root, arr[i], &result);`
`  ``return` `result;`
`}`
http://www.geeksforgeeks.org/count-inversions-in-an-array-set-2-using-self-balancing-bst/
BIT basically supports two operations for an array arr[] of size n:
1. Sum of elements till arr[i] in O(Log n) time.
2. Update an array element in O(Log n) time.
BIT is implemented using an array and works in form of trees. Note that there are two ways of looking at BIT as a tree.
1. The sum operation where parent of index x is "x - x(x & -x)".
2. The update operation where parent of index x is "x + x(x & -x)".
We recommend you refer Binary Indexed Tree (BIT) before further reading this post.
Basic Approach using BIT of size Θ(maxElement):
The idea is to iterate the array from n-1 to 0. When we are at i'th index, we check how many numbers less than arr[i] are present in BIT and add it to the result. To get the count of smaller elements, getSum() of BIT is used. In his basic idea, BIT is represented as an array of size equal to maximum element plus one. So that elements can be used as an index.
After that we add current element to to the BIT[] by doing an update operation that updates count of current element from 0 to 1, and therefore updates ancestors of current element in BIT (See update() in BIT for details).
Time Complexity :- The update function and getSum function runs for O(log(maximumelement)) and we are iterating over n elements. So overall time complexity is : O(nlog(maximumelement)).
Auxiliary space : O(maxElement)
`// Returns sum of arr[0..index]. This function assumes`
`// that the array is preprocessed and partial sums of`
`// array elements are stored in BITree[].`
`int` `getSum(``int` `BITree[], ``int` `index)`
`{`
`    ``int` `sum = 0; ``// Initialize result`
`    ``// Traverse ancestors of BITree[index]`
`    ``while` `(index > 0)`
`    ``{`
`        ``// Add current element of BITree to sum`
`        ``sum += BITree[index];`
`        ``// Move index to parent node in getSum View`
`        ``index -= index & (-index);`
`    ``}`
`    ``return` `sum;`
`}`
`// Updates a node in Binary Index Tree (BITree) at given index`
`// in BITree.  The given value 'val' is added to BITree[i] and`
`// all of its ancestors in tree.`
`void` `updateBIT(``int` `BITree[], ``int` `n, ``int` `index, ``int` `val)`
`{`
`    ``// Traverse all ancestors and add 'val'`
`    ``while` `(index <= n)`
`    ``{`
`       ``// Add 'val' to current node of BI Tree`
`       ``BITree[index] += val;`
`       ``// Update index to that of parent in update View`
`       ``index += index & (-index);`
`    ``}`
`}`
`// Returns inversion count arr[0..n-1]`
`int` `getInvCount(``int` `arr[], ``int` `n)`
`{`
`    ``int` `invcount = 0; ``// Initialize result`
`    ``// Find maximum element in arr[]`
`    ``int` `maxElement = 0;`
`    ``for` `(``int` `i=0; i<n; i++)`
`        ``if` `(maxElement < arr[i])`
`            ``maxElement = arr[i];`
`    ``// Create a BIT with size equal to maxElement+1 (Extra`
`    ``// one is used so that elements can be directly be`
`    ``// used as index)`
`    ``int` `BIT[maxElement+1];`
`    ``for` `(``int` `i=1; i<=maxElement; i++)`
`        ``BIT[i] = 0;`
`    ``// Traverse all elements from right.`
`    ``for` `(``int` `i=n-1; i>=0; i--)`
`    ``{`
`        ``// Get count of elements smaller than arr[i]`
`        ``invcount += getSum(BIT, arr[i]-1);`
`        ``// Add current element to BIT`
`        ``updateBIT(BIT, maxElement, arr[i], 1);`
`    ``}`
`    ``return` `invcount;`
`}`
Better Approach using BIT of size Θ(n):
The problem with the previous approach is that it doesn't work for negative numbers as index cannot be negative. Also by updating the value till maximum element we waste time and space as it is quite possible that we may never use intermediate value. For example, lots of space an time is wasted for an array like {1, 100000}.
The idea is to convert given array to an array with values from 1 to n and relative order of smaller and greater elements remains
```Example :-
arr[] = {7, -90, 100, 1}

It gets  converted to,
arr[] = {3, 1, 4 ,2 }
as -90 < 1 < 7 < 100.
```
We only have to make BIT[] of number of elements instead of maximum element.
Changing element will not have any change in the answer as the greater elements remain greater and at same position.
Time Complexity :- The update function and getSum function runs for O(log(n)) and we are iterating over n elements. So overall time complexity is : O(nlogn).
Auxiliary space : O(n)
`// Converts an array to an array with values from 1 to n`
`// and relative order of smaller and greater elements remains`
`// same.  For example, {7, -90, 100, 1} is converted to`
`// {3, 1, 4 ,2 }`
`void` `convert(``int` `arr[], ``int` `n)`
`{`
`    ``// Create a copy of arrp[] in temp and sort the temp array`
`    ``// in increasing order`
`    ``int` `temp[n];`
`    ``for` `(``int` `i=0; i<n; i++)`
`        ``temp[i] = arr[i];`
`    ``sort(temp, temp+n);`
`    ``// Traverse all array elements`
`    ``for` `(``int` `i=0; i<n; i++)`
`    ``{`
`        ``// lower_bound() Returns pointer to the first element`
`        ``// greater than or equal to arr[i]`
`        ``arr[i] = lower_bound(temp, temp+n, arr[i]) - temp + 1;`
`    ``}`
`}`
`// Returns inversion count arr[0..n-1]`
`int` `getInvCount(``int` `arr[], ``int` `n)`
`{`
`    ``int` `invcount = 0; ``// Initialize result`
`     ``// Convert arr[] to an array with values from 1 to n and`
`     ``// relative order of smaller and greater elements remains`
`     ``// same.  For example, {7, -90, 100, 1} is converted to`
`    ``//  {3, 1, 4 ,2 }`
`    ``convert(arr, n);`
`    ``// Create a BIT with size equal to maxElement+1 (Extra`
`    ``// one is used so that elements can be directly be`
`    ``// used as index)`
`    ``int` `BIT[n+1];`
`    ``for` `(``int` `i=1; i<=n; i++)`
`        ``BIT[i] = 0;`
`    ``// Traverse all elements from right.`
`    ``for` `(``int` `i=n-1; i>=0; i--)`
`    ``{`
`        ``// Get count of elements smaller than arr[i]`
`        ``invcount += getSum(BIT, arr[i]-1);`
`        ``// Add current element to BIT`
`        ``updateBIT(BIT, n, arr[i], 1);`
`    ``}`
`    ``return` `invcount;`
`}`
Count Inversions in an array | GeeksforGeeks