diff --git a/arrays/README.md b/arrays/README.md new file mode 100644 index 00000000..e26e2c97 --- /dev/null +++ b/arrays/README.md @@ -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) diff --git a/arrays/c-or-cpp/count-inversions.cpp b/arrays/c-or-cpp/count-inversions.cpp new file mode 100644 index 00000000..0ec69de2 --- /dev/null +++ b/arrays/c-or-cpp/count-inversions.cpp @@ -0,0 +1,55 @@ +// Algorithm Type: Divide & Conquer +// Time Complexity: O(n*log(n)) + +#include +#include +#include +#include +using namespace std; + +long long int count_split_inv(vector &vec, vector &left, vector &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 &vec) { + int size = vec.size(); + if (size == 1) { + return 0; + } + vector left(vec.begin(), vec.begin() + size / 2); + vector 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 v{8, 2, 1, 5, 7, 3, 9, 2, 0, 1}; + cout << count_inversions(v) << endl; + return 0; +} diff --git a/arrays/java/count-inversions.java b/arrays/java/count-inversions.java new file mode 100644 index 00000000..472a7c3b --- /dev/null +++ b/arrays/java/count-inversions.java @@ -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... "); + } + + } +} diff --git a/arrays/js/count-inversions.js b/arrays/js/count-inversions.js new file mode 100644 index 00000000..7a828f2f --- /dev/null +++ b/arrays/js/count-inversions.js @@ -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)); diff --git a/arrays/python/count-inversions.py b/arrays/python/count-inversions.py new file mode 100644 index 00000000..16190435 --- /dev/null +++ b/arrays/python/count-inversions.py @@ -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))