-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathChallenge.java
More file actions
144 lines (110 loc) · 4.29 KB
/
Challenge.java
File metadata and controls
144 lines (110 loc) · 4.29 KB
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package com.java.cci.practice;
import java.util.Arrays;
public class Challenge {
private static final int[] VALUE_SET_1 = {5, 1, 20, 6, 4, 5};
private static final int[] VALUE_SET_2 = {6, 8, 4, 2, 1};
private static final int[] VALUE_SET_3 = {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
private static final int[] VALUE_SET_4 = {4, 2, 1, 3, 1, 2};
private static final int[] VALUE_SET_5 = {3, 1, 3, 5, 2, 4, 6};
private static final int[] VALUE_SET_6 = {
0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10
};
/*
Inversion in a list of numbers indicates how far a list is from being sorted. Let us say we
have a variable:
arr = [1,2,4,3,5,6]
in the variable arr we have one inversion of the numbers 4 and 3 because they are in an
unsorted order. Thus, the formal definition will be:
Given an array arr, an inversion would occur if arr[i] > arr[j] and i < j.
Just to cement what an inversion is, I would re-define it using other words:
If an element on the left is greater than an element on the right, then that is an
inversion.
*/
private static int countInversions(final int[] values) {
if (values.length <= 1) return 0;
// TODO Your task is to write code that determines how many inversions exist in the array
// "values" and return that value to the caller.
return 0;
}
private static void checkSolution(final int[] values) {
final long started = System.currentTimeMillis();
final int count = Challenge.countInversions(Arrays.copyOfRange(values, 1, values.length));
final long runtime = System.currentTimeMillis() - started;
System.out.println(
"==============================================================================");
System.out.println(
String.format(
"Data size: %d elements Runtime: %dms\nExpected: %d Counted: %d %s",
values.length,
runtime,
values[0],
count,
values[0] == count ? "<CORRECT>" : "<!>INCORRECT<!>"));
System.out.println(
"==============================================================================");
}
public static void main(String[] args) {
// System.out.println(
// mergeSortAndCount(VALUE_SET_1, 1, VALUE_SET_1.length - 1));
System.out.println(
mergeSortAndCount(VALUE_SET_2, 1, VALUE_SET_2.length - 1));
// System.out.println(
// mergeSortAndCount(VALUE_SET_3, 1, VALUE_SET_3.length - 1));
// System.out.println(
// mergeSortAndCount(VALUE_SET_4, 1, VALUE_SET_4.length - 1));
// System.out.println(
// mergeSortAndCount(VALUE_SET_5, 1, VALUE_SET_5.length - 1));
// System.out.println(
// mergeSortAndCount(VALUE_SET_6, 0, VALUE_SET_6.length - 1));
// generate large test data
// int[] largeData = new int[1000001];
// largeData[0] = 1783293664;
// for (int index = 1; index < largeData.length; index++) {
// largeData[index] = largeData.length - 1 - index;
// }
// checkSolution(largeData);
}
// Function to count the number of inversions
// during the merge process
private static int mergeAndCount(int[] arr, int l,
int m, int r)
{
// Left subarray
int[] left = Arrays.copyOfRange(arr, l, m + 1);
// Right subarray
int[] right = Arrays.copyOfRange(arr, m + 1, r + 1);
int i = 0, j = 0, k = l, swaps = 0;
while (i < left.length && j < right.length) {
if (left[i] <= right[j])
arr[k++] = left[i++];
else {
arr[k++] = right[j++];
swaps += (m + 1) - (l + i);
}
}
while (i < left.length)
arr[k++] = left[i++];
while (j < right.length)
arr[k++] = right[j++];
return swaps;
}
private static int mergeSortAndCount(int[] arr, int l,
int r)
{
// Keeps track of the inversion count at a
// particular node of the recursion tree
int count = 0;
if (l < r) {
int m = (l + r) / 2;
// Total inversion count = left subarray count
// + right subarray count + merge count
// Left subarray count
count += mergeSortAndCount(arr, l, m);
// Right subarray count
count += mergeSortAndCount(arr, m + 1, r);
// Merge count
count += mergeAndCount(arr, l, m, r);
}
return count;
}
}