💻
Algorithm
  • README
  • Array
    • At Most To Equal
    • Count Inversions In An Array
    • Interleaving Placement
    • Kadane
    • Left To Right State Transition
    • Permutation
    • Quick Select
    • Sliding Window
    • Two Pointers
  • Binary Tree
    • Avl Tree
    • Binary Search Tree
    • Serialization And Deserialization
    • Traversal
  • Company
    • Facebook
  • Cpp
    • Array
    • Memset 3 F
    • Overflow
  • Data Structure
    • Binary Indexed Tree
    • Segment Tree And Binary Index Tree
    • Segment Tree
    • Stack
    • Trie
    • Union Find
  • Dynamic Programming
    • Knapsack
      • 0 1 Knapsack
      • Bounded Knapsack
      • Unbounded Knapsack
    • Bitmask Dp
    • Dp On Subsets
    • Dp On Tree
    • Dp With Sorting
    • Selective State Dp
    • Travelling Salesperson
  • Graph
    • Minimum Spanning Tree
      • Kruskal
      • Prim
    • Shortest Path
      • Bellman Ford
      • Dijkstra
      • Floyd Warshall
      • Johnson
      • Shortest Path Faster Algorithm
    • Bi Directional Breadth First Search
    • Bipartite
    • Breadth First Search
    • Component Coloring
    • Component Count
    • Depth First Search
    • Eulerian Path
    • Maximum Bipartite Matching
    • Tarjan
    • Topological Sort
    • Tree Diameter
    • Tree Ring Order Traversal
  • Greedy
    • Greedy Scheduling
    • Regret Greedy
  • Math
    • Catalan Number
    • Combinatorics
    • Factorial
    • Factorization
    • Fast Pow
    • Gcd
    • Geometry
    • Get Digits
    • Lcm
    • Median Minimizes Sum Of Absolute Deviations
    • Mode
    • Modular Multiplicative Inverse
    • Palindrome
    • Prime Number
    • Round Up
    • Sieve Of Eratosthenes
    • Stars And Bars
    • Sum Of Sequence
  • Miscellaneous
    • Bin Packing
    • Floyds Tortoise And Hare
    • Hungarian
    • Palindrome
  • Sort
    • Bubble Sort
    • Cycle Sort
    • Heap Sort
    • Merge Sort
    • Quick Sort
    • Sorting
  • Stl
    • Cpp Stl
    • Istringstream
    • Lower Bound Upper Bound
    • Priority Queue
  • String
    • Kmp
    • Manacher
    • Rabin Karp
    • String Processing
    • Z
  • Backtracking
  • Binary Answer
  • Binary Lifting
  • Binary Search
  • Bit Manipulation
  • Date
  • Difference Array
  • Discretization
  • Divide And Conquer
  • Gray Code
  • Great Problems For Practice
  • Interval Scheduling Maximization
  • Io Optimization
  • K Subset Partitioning
  • Line Sweep
  • Longest Common Subsequence
  • Longest Increasing Subsequence
  • Meet In The Middle
  • Minmax
  • Mono Deque
  • Monotonic Stack
  • Offline Query
  • P And Np
  • Prefix State Map
  • Prefix Sum
  • Random
  • Reservoir Sampling
  • Reverse Polish Notation
  • Sqrt Decomposition
Powered by GitBook
On this page
  • Brute force
  • Merge Sort (Divide and Conquer)

Was this helpful?

  1. Array

Count Inversions In An Array

In array A, two elements A[i] and A[j] form an inversion if A[i] > A[j] and i < j

The count of inversion of an array indicates how far the array is from sorted. If the array is already sorted, its inversion count is 0. If the array is sorted in the reverse order then its inversion count is the maximum.

Brute force

Brute force method is trivial -- for each number, count how many number to its right is smaller than it. The time complexit is O(N^2) and space complexity is O(1).

Merge Sort (Divide and Conquer)

During the merge, if we need to select a number x from the right part, we can add the inversion count by the count of remaining items in the left part, because they must be all greater than x.

For example, assume we want to merge [1,3] and [0,2].

  • we need to first select the 0 and there are 2 numbers left in the left part, we add the count by 2.

  • select 1 from the left part, leave the count unchanged.

  • select 2 from the right part, add the count by 1 because there is only one 3 left in the left part.

  • select 3 from the left part, leave the count unchanged.

So in total there are 2 + 1 = 3 inversions.

// Time: O(NlogN)
// Space: O(N)
long long _mergeSort(vector<int> &A, vector<int> &tmp, int start, int end) {
    if (start + 1 >= end) return 0;
    long long mid = (start + end) / 2, cnt = 0;
    cnt += _mergeSort(A, tmp, start, mid);
    cnt += _mergeSort(A, tmp, mid, end);
    for (int i = start, j = mid, k = 0; i < mid || j < end; ++k) {
        if (i >= mid || (j < end && A[j] < A[i])) {
            tmp[k] = A[j++];
            cnt += mid - i;
        } else tmp[k] = A[i++];
    }
    for (int i = start; i < end; ++i) A[i] = tmp[i - start];
    return cnt;
}
long long mergeSort(vector<int> &A, int start, int end) {
    vector<int> tmp(A.size());
    return _mergeSort(A, tmp, start, end);
}
long long countInversions(vector<int>& A) {
    return mergeSort(A, 0, A.size());
}
PreviousAt Most To EqualNextInterleaving Placement

Last updated 4 years ago

Was this helpful?