Skip to content

Commit 0edbada

Browse files
authored
Longest increasing subsequence added (#364)
1 parent 0dd2c03 commit 0edbada

File tree

3 files changed

+95
-4
lines changed

3 files changed

+95
-4
lines changed

pydatastructs/linear_data_structures/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
longest_common_subsequence,
3636
is_ordered,
3737
upper_bound,
38-
lower_bound
38+
lower_bound,
39+
longest_increasing_subsequence
3940
)
4041
__all__.extend(algorithms.__all__)

pydatastructs/linear_data_structures/algorithms.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
'cocktail_shaker_sort',
1616
'quick_sort',
1717
'longest_common_subsequence',
18+
'is_ordered',
1819
'upper_bound',
1920
'lower_bound',
20-
'is_ordered'
21+
'longest_increasing_subsequence'
2122
]
2223

2324
def _merge(array, sl, el, sr, er, end, comp):
@@ -978,3 +979,62 @@ def lower_bound(array, value, **kwargs):
978979
index = mid
979980
inclusive_end = mid - 1
980981
return index
982+
983+
def longest_increasing_subsequence(array):
984+
"""
985+
Returns the longest increasing subsequence (as a OneDimensionalArray) that
986+
can be obtained from a given OneDimensionalArray. A subsequence
987+
of an array is an ordered subset of the array's elements having the same
988+
sequential ordering as the original array. Here, an increasing
989+
sequence stands for a strictly increasing sequence of numbers.
990+
991+
Parameters
992+
==========
993+
994+
array: OneDimensionalArray
995+
The given array in the form of a OneDimensionalArray
996+
997+
Returns
998+
=======
999+
1000+
output: OneDimensionalArray
1001+
Returns the longest increasing subsequence that can be obtained
1002+
from the given array
1003+
1004+
Examples
1005+
========
1006+
1007+
>>> from pydatastructs import lower_bound, OneDimensionalArray as ODA
1008+
>>> from pydatastructs import longest_increasing_subsequence as LIS
1009+
>>> array = ODA(int, [2, 5, 3, 7, 11, 8, 10, 13, 6])
1010+
>>> longest_inc_subsequence = LIS(array)
1011+
>>> longest_inc_subsequence
1012+
[2, 3, 7, 8, 10, 13]
1013+
>>> array2 = ODA(int, [3, 4, -1, 5, 8, 2, 2 ,2, 3, 12, 7, 9, 10])
1014+
>>> longest_inc_subsequence = LIS(array2)
1015+
>>> longest_inc_subsequence
1016+
[-1, 2, 3, 7, 9, 10]
1017+
"""
1018+
n = len(array)
1019+
dp = [0]*n
1020+
parent = [-1]*n
1021+
length = 0
1022+
for i in range(1, n):
1023+
if array[i] <= array[dp[0]]:
1024+
dp[0] = i
1025+
elif array[dp[length]] < array[i]:
1026+
length += 1
1027+
dp[length] = i
1028+
parent[i] = dp[length - 1]
1029+
else:
1030+
curr_array = [array[dp[i]] for i in range(length)]
1031+
ceil = lower_bound(curr_array, array[i])
1032+
dp[ceil] = i
1033+
parent[i] = dp[ceil - 1]
1034+
ans = []
1035+
1036+
last_index = dp[length]
1037+
while last_index != -1:
1038+
ans[:0] = [array[last_index]]
1039+
last_index = parent[last_index]
1040+
return ans

pydatastructs/linear_data_structures/tests/test_algorithms.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
from pydatastructs import (
22
merge_sort_parallel, DynamicOneDimensionalArray,
33
OneDimensionalArray, brick_sort, brick_sort_parallel,
4-
heapsort, matrix_multiply_parallel, counting_sort, bucket_sort, cocktail_shaker_sort, quick_sort, longest_common_subsequence,
5-
is_ordered, upper_bound, lower_bound)
4+
heapsort, matrix_multiply_parallel, counting_sort, bucket_sort,
5+
cocktail_shaker_sort, quick_sort, longest_common_subsequence, is_ordered,
6+
upper_bound, lower_bound, longest_increasing_subsequence)
7+
68

79
from pydatastructs.utils.raises_util import raises
810
import random
@@ -241,3 +243,31 @@ def test_lower_bound():
241243
output = lower_bound(arr8, 6, end=3, comp=lambda x, y: x > y)
242244
expected_result = 1
243245
assert expected_result == output
246+
247+
def test_longest_increasing_subsequence():
248+
ODA = OneDimensionalArray
249+
250+
arr1 = ODA(int, [2, 5, 3, 7, 11, 8, 10, 13, 6])
251+
output = longest_increasing_subsequence(arr1)
252+
expected_result = [2, 3, 7, 8, 10, 13]
253+
assert expected_result == output
254+
255+
arr2 = ODA(int, [3, 4, -1, 5, 8, 2, 2, 2, 3, 12, 7, 9, 10])
256+
output = longest_increasing_subsequence(arr2)
257+
expected_result = [-1, 2, 3, 7, 9, 10]
258+
assert expected_result == output
259+
260+
arr3 = ODA(int, [6, 6, 6, 19, 9])
261+
output = longest_increasing_subsequence(arr3)
262+
expected_result = [6, 9]
263+
assert expected_result == output
264+
265+
arr4 = ODA(int, [5, 4, 4, 3, 3, 6, 6, 8])
266+
output = longest_increasing_subsequence(arr4)
267+
expected_result = [3, 6, 8]
268+
assert expected_result == output
269+
270+
arr5 = ODA(int, [7, 6, 6, 6, 5, 4, 3])
271+
output = longest_increasing_subsequence(arr5)
272+
expected_result = [3]
273+
assert expected_result == output

0 commit comments

Comments
 (0)