Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7a7549d

Browse files
Closes #91 Bug fix
1 parent e6ff7a8 commit 7a7549d

File tree

2 files changed

+36
-16
lines changed

2 files changed

+36
-16
lines changed
Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package com.jwetherell.algorithms.sequence;
22

3-
import com.jwetherell.algorithms.search.LowerBound;
4-
5-
import java.util.Arrays;
6-
73
/**
84
* In computer science, the longest increasing subsequence problem is to find a subsequence of a given sequence in which the subsequence's elements are in sorted order, lowest to highest, and in
95
* which the subsequence is as long as possible. This subsequence is not necessarily contiguous, or unique.
@@ -20,19 +16,43 @@ private LongestIncreasingSubsequence() { }
2016
/**
2117
* Longest increasing subsequence solved using dynamic programming.
2218
*/
23-
public static int[] getLongestIncreasingSubsequence(int[] sequence) {
24-
final int[] resultSequence = new int[sequence.length];
19+
public static int[] getLongestIncreasingSubsequence(int[] X) {
20+
final int[] P = new int[X.length];
21+
final int[] M = new int[X.length+1];
22+
int L = 0;
23+
for (int i=0; i<X.length; i++) {
24+
// Binary search for the largest positive j ≤ L such that X[M[j]] < X[i]
25+
int lo = 1;
26+
int hi = L;
27+
while (lo <= hi) {
28+
final int mid = (int) Math.ceil((lo + hi) / 2);
29+
if (X[M[mid]] < X[i])
30+
lo = mid+1;
31+
else
32+
hi = mid-1;
33+
}
34+
35+
// After searching, lo is 1 greater than the length of the longest prefix of X[i]
36+
final int newL = lo;
37+
38+
// The predecessor of X[i] is the last index of the subsequence of length newL-1
39+
P[i] = M[newL-1];
40+
M[newL] = i;
41+
42+
if (newL > L) {
43+
// If we found a subsequence longer than any we've found yet, update L
44+
L = newL;
45+
}
46+
}
2547

26-
int resultLength = 0;
27-
for (int i = 0; i < sequence.length; ++i) {
28-
// try to find the best place for new element in sorted result
29-
final int pos = LowerBound.lowerBound(resultSequence, resultLength, sequence[i]); //O(log n)
30-
// if the best place is at the end increase result length
31-
if (pos >= resultLength)
32-
resultLength++;
33-
resultSequence[pos] = sequence[i];
48+
// Reconstruct the longest increasing subsequence
49+
final int[] S = new int[L];
50+
int k = M[L];
51+
for (int i=L-1; i>=0; i--) {
52+
S[i] = X[k];
53+
k = P[k];
3454
}
3555

36-
return Arrays.copyOfRange(resultSequence, 0, resultLength);
56+
return S;
3757
}
3858
}

‎test/com/jwetherell/algorithms/sequence/test/Sequences.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public void testLongestIncreasingSubsequence() {
141141
sequencesLis.add(new int[]{1, 2, 3});
142142

143143
sequences.add(new int[]{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15});
144-
sequencesLis.add(new int[]{0, 1, 3, 7, 11, 15});
144+
sequencesLis.add(new int[]{0, 2, 6, 9, 11, 15});
145145

146146
assertTrue("Longest increasing subsequence error. Sequences size=" + sequences.size() + " SequencesList size:" + sequencesLis.size(), sequences.size() == sequencesLis.size());
147147

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /