Skip to content

Commit 661d7f3

Browse files
Largest nonincreasing subsequence task, that working with O(n*log(n)) time complexity
1 parent 16cc332 commit 661d7f3

File tree

1 file changed

+81
-0
lines changed
  • src/algorithms/largest_nonincreasing_subsequence

1 file changed

+81
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package algorithms.largest_nonincreasing_subsequence;
2+
3+
import java.util.Arrays;
4+
import java.util.Scanner;
5+
6+
public class Main {
7+
private void run() {
8+
Scanner scanner = new Scanner(System.in);
9+
int arraySize = scanner.nextInt();
10+
int[] array = new int[arraySize];
11+
for (int i = 0; i < arraySize; i++) {
12+
array[i] = scanner.nextInt();
13+
}
14+
int[] subsequence = calcLargestNonincreasingSubsequence(array);
15+
StringBuilder outputBuilder = new StringBuilder();
16+
outputBuilder.append(String.format("%d\n", subsequence.length));
17+
for (int index : subsequence) {
18+
outputBuilder.append(String.format("%d ", index + 1));
19+
}
20+
System.out.println(outputBuilder.toString());
21+
}
22+
23+
private int lowerBound(int[] array, int length, int searchElement) {
24+
int left = -1;
25+
int right = length;
26+
while (left + 1 < right) {
27+
int current = (left + right) >> 1;
28+
if (array[current] >= searchElement) {
29+
left = current;
30+
} else {
31+
right = current;
32+
}
33+
}
34+
return right;
35+
}
36+
37+
private int[] calcLargestNonincreasingSubsequence(int[] array) {
38+
int[] sequencesEndsIndices = new int[array.length];
39+
int[] sequencesEnds = new int[array.length];
40+
Arrays.setAll(sequencesEnds, index -> Integer.MIN_VALUE);
41+
sequencesEnds[0] = array[0];
42+
int[] prevPositions = new int[array.length];
43+
Arrays.setAll(prevPositions, index -> -1);
44+
int length = 1;
45+
46+
for (int i = 1; i < array.length; i++) {
47+
int pos = lowerBound(sequencesEnds, length, array[i]);
48+
if (pos == length) {
49+
length++;
50+
sequencesEnds[pos] = array[i];
51+
sequencesEndsIndices[pos] = i;
52+
prevPositions[i] = sequencesEndsIndices[pos - 1]; // pos - 1;
53+
}
54+
else if (pos == 0) {
55+
if (sequencesEnds[pos] <= array[i]) {
56+
sequencesEnds[pos] = array[i];
57+
sequencesEndsIndices[pos] = i;
58+
prevPositions[i] = -1;
59+
}
60+
}
61+
else if (sequencesEnds[pos] <= array[i] && array[i] <= sequencesEnds[pos - 1]) {
62+
sequencesEnds[pos] = array[i];
63+
sequencesEndsIndices[pos] = i;
64+
prevPositions[i] = sequencesEndsIndices[pos - 1]; // pos - 1;
65+
}
66+
}
67+
68+
int[] sequenceIndices = new int[length];
69+
int pos = sequencesEndsIndices[length - 1];
70+
int index = length - 1;
71+
while (pos != -1) {
72+
sequenceIndices[index--] = pos;
73+
pos = prevPositions[pos];
74+
}
75+
return sequenceIndices;
76+
}
77+
78+
public static void main(String[] args) {
79+
new Main().run();
80+
}
81+
}

0 commit comments

Comments
 (0)