added algo to count inversions in an array in C++, Python, JavaScript and Java (#79)

* algo to count inversions in array

Added in C++, Python, JavaScript and Java

* Added comments

* Rename arrays/javascript/count-inversions.js to arrays/js/count-inversions.js

* Update count-inversions.cpp

* Update count-inversions.java

* Update count-inversions.js

* Update count-inversions.py
pull/87/head
Atin Bainada 2021-02-24 01:44:09 +05:30 committed by GitHub
parent 8cb86de0d7
commit feb6dc99be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 221 additions and 0 deletions

17
arrays/README.md 100644
View File

@ -0,0 +1,17 @@
# Algorithms related to arrays
### C or C++
1. [Counting Inversions](c-or-cpp/count-inversions.cpp)
### Python
1. [Counting Inversions](python/count-inversions.py)
### JavaScript
1. [Counting Inversions](js/count-inversions.js)
### Java
1. [Counting Inversions](java/count-inversions.java)

View File

@ -0,0 +1,55 @@
// Algorithm Type: Divide & Conquer
// Time Complexity: O(n*log(n))
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
using namespace std;
long long int count_split_inv(vector<int> &vec, vector<int> &left, vector<int> &right) {
long long int split_inv = 0;
int ridx = 0, lidx = 0;
int size = vec.size();
int lsize = left.size();
int rsize = right.size();
for (int i = 0; i < size; i++) {
if (lidx != lsize && ridx != rsize) {
if (right[ridx] <= left[lidx]) {
vec[i] = right[ridx];
ridx++;
split_inv += lsize - lidx;
} else {
vec[i] = left[lidx];
lidx++;
}
} else if (lidx == lsize) {
vec[i] = right[ridx];
ridx++;
} else if (ridx == rsize) {
vec[i] = left[lidx];
lidx++;
}
}
return split_inv;
}
long long int count_inversions(vector<int> &vec) {
int size = vec.size();
if (size == 1) {
return 0;
}
vector<int> left(vec.begin(), vec.begin() + size / 2);
vector<int> right(vec.begin() + size / 2, vec.end());
long long int left_inv = count_inversions(left);
long long int right_inv = count_inversions(right);
long long int split_inv = count_split_inv(vec, left, right);
return left_inv + right_inv + split_inv;
}
int main() {
vector<int> v{8, 2, 1, 5, 7, 3, 9, 2, 0, 1};
cout << count_inversions(v) << endl;
return 0;
}

View File

@ -0,0 +1,59 @@
// Algorithm Type: Divide & Conquer
// Time Complexity: O(n*log(n))
import java.io.File;
import java.lang.reflect.Array;
import java.util.*;
public class inversions {
private static long count_split_inv(int[] arr, int[] left, int[] right) {
long split_inv = 0;
int ridx = 0, lidx = 0;
int size = arr.length;
int rsize = right.length;
int lsize = left.length;
for (int i = 0; i < size; i++) {
if (lidx != lsize && ridx != rsize) {
if (right[ridx] <= left[lidx]) {
arr[i] = right[ridx];
ridx++;
split_inv += lsize - lidx;
} else {
arr[i] = left[lidx];
lidx++;
}
} else if (lidx == lsize) {
arr[i] = right[ridx];
ridx++;
} else if (ridx == rsize) {
arr[i] = left[lidx];
lidx++;
}
}
return split_inv;
}
private static long count_inversions(int[] arr) {
int size = arr.length;
if (size == 1) {
return 0;
}
int[] left = Arrays.copyOfRange(arr, 0, size / 2);
int[] right = Arrays.copyOfRange(arr, size / 2, size);
long left_inv = count_inversions(left);
long right_inv = count_inversions(right);
long split_inv = count_split_inv(arr, left, right);
return left_inv + right_inv + split_inv;
}
public static void main(String[] args) {
try {
int[] arr = {8, 2, 1, 5, 7, 3, 9, 2, 0, 1};
System.out.println(count_inversions(arr));
} catch (Exception e) {
System.out.println("Err... ");
}
}
}

View File

@ -0,0 +1,48 @@
// Algorithm Type: Divide & Conquer
// Time Complexity: O(n*log(n))
function count_split_inv(arr, left, right) {
let split_inv, lidx, ridx;
split_inv = ridx = lidx = 0;
let size = arr.length;
let lsize = left.length;
let rsize = right.length;
for (let i = 0; i < size; i++) {
if (lidx != lsize && ridx != rsize) {
if (right[ridx] <= left[lidx]) {
arr[i] = right[ridx];
ridx++;
split_inv += lsize - lidx;
} else {
arr[i] = left[lidx];
lidx++;
}
} else if (lidx == lsize) {
arr[i] = right[ridx];
ridx++;
} else if (ridx == rsize) {
arr[i] = left[lidx];
lidx++;
}
}
return split_inv;
}
function count_inversions(arr) {
let size = arr.length;
if (size == 1) {
return 0;
}
let mid = parseInt(size / 2);
let left = arr.slice(0, mid);
let right = arr.slice(mid, size);
let left_inv = count_inversions(left);
let right_inv = count_inversions(right);
let split_inv = count_split_inv(arr, left, right);
return left_inv + right_inv + split_inv;
}
var arr = [8, 2, 1, 5, 7, 3, 9, 2, 0, 1];
console.log(count_inversions(arr));

View File

@ -0,0 +1,42 @@
"""
Algorithm Type: Divide & Conquer
Time Complexity: O(n*log(n))
"""
def count_split_inv(arr, left, right):
split_inv = ridx = lidx = 0
size = len(arr)
lsize = len(left)
rsize = len(right)
for i in range(size):
if lidx != lsize and ridx != rsize:
if right[ridx] <= left[lidx]:
arr[i] = right[ridx]
ridx += 1
split_inv += lsize - lidx
else:
arr[i] = left[lidx]
lidx += 1
elif lidx == lsize:
arr[i] = right[ridx]
ridx += 1
elif ridx == rsize:
arr[i] = left[lidx]
lidx += 1
return split_inv;
def count_inversions(arr):
size = len(arr)
if size == 1:
return 0
mid = int(size/2)
left = arr[:mid]
right = arr[mid:]
l_inv = count_inversions(left)
r_inv = count_inversions(right)
split_inv = count_split_inv(arr, left, right)
return l_inv + r_inv + split_inv
numbers = [8, 2, 1, 5, 7, 3, 9, 2, 0, 1]
print(count_inversions(numbers))