-
Notifications
You must be signed in to change notification settings - Fork 0
/
inversions.cpp
73 lines (64 loc) · 1.87 KB
/
inversions.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include "util.h"
// Given an array, count the number of inversions in the array, i.e.,
// the number of pairs, where the larger number occurs before a smaller number.
// O(n**2) approach.
int inversionsNaive(vector<int> v) {
int count = 0;
for (int i = 0; i < v.size(); i++) {
for (int j = i + 1; j < v.size(); j++) {
if (v[i] > v[j]) {
count++;
}
}
}
return count;
}
int inversionUsingSort(vector<int> &v) {
if (v.size() <= 1) {
return 0;
}
int count = 0;
// Divide the array into two parts.
vector<int> firstPart(v.begin(), v.begin() + v.size() / 2);
vector<int> secondPart(v.begin() + v.size() / 2, v.end());
count += inversionUsingSort(firstPart);
count += inversionUsingSort(secondPart);
// Merge the arrays.
auto first = firstPart.begin();
auto second = secondPart.begin();
size_t idx = 0;
for (; first != firstPart.end() || second != secondPart.end();) {
if (first == firstPart.end()) {
v[idx++] = *second;
second++;
} else if (second == secondPart.end()) {
v[idx++] = *first;
first++;
} else {
if (*first <= *second) {
v[idx++] = *first;
first++;
} else {
// This is the inversion case. We are inserting an element from the
// second vector into the merged vector. All the remaining elements in
// the first vector are inversions w.r.t. the element being added from
// the second. Note that this counts duplicates too.
count += std::distance(first, firstPart.end());
v[idx++] = *second;
second++;
}
}
}
return count;
}
int inversions(const vector<int> &v) {
// Make a copy of the vector.
vector<int> vc = v;
return inversionUsingSort(vc);
}
int main() {
{
vector<int> t = {4, 6, 1, 2, 3, 9, 11, 7, 8, 101, 33, 22, 121, 24, 4};
EXPECT_EQ(inversionsNaive(t), inversions(t));
}
}