Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pydatastructs/linear_data_structures/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
longest_common_subsequence,
is_ordered,
upper_bound,
lower_bound
lower_bound,
longest_increasing_subsequence
)
__all__.extend(algorithms.__all__)
62 changes: 61 additions & 1 deletion pydatastructs/linear_data_structures/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
'cocktail_shaker_sort',
'quick_sort',
'longest_common_subsequence',
'is_ordered',
'upper_bound',
'lower_bound',
'is_ordered'
'longest_increasing_subsequence'
]

def _merge(array, sl, el, sr, er, end, comp):
Expand Down Expand Up @@ -978,3 +979,62 @@ def lower_bound(array, value, **kwargs):
index = mid
inclusive_end = mid - 1
return index

def longest_increasing_subsequence(array):
"""
Returns the longest increasing subsequence (as a OneDimensionalArray) that
can be obtained from a given OneDimensionalArray. A subsequence
of an array is an ordered subset of the array's elements having the same
sequential ordering as the original array. Here, an increasing
sequence stands for a strictly increasing sequence of numbers.

Parameters
==========

array: OneDimensionalArray
The given array in the form of a OneDimensionalArray

Returns
=======

output: OneDimensionalArray
Returns the longest increasing subsequence that can be obtained
from the given array

Examples
========

>>> from pydatastructs import lower_bound, OneDimensionalArray as ODA
>>> from pydatastructs import longest_increasing_subsequence as LIS
>>> array = ODA(int, [2, 5, 3, 7, 11, 8, 10, 13, 6])
>>> longest_inc_subsequence = LIS(array)
>>> longest_inc_subsequence
[2, 3, 7, 8, 10, 13]
>>> array2 = ODA(int, [3, 4, -1, 5, 8, 2, 2 ,2, 3, 12, 7, 9, 10])
>>> longest_inc_subsequence = LIS(array2)
>>> longest_inc_subsequence
[-1, 2, 3, 7, 9, 10]
"""
n = len(array)
dp = [0]*n
parent = [-1]*n
length = 0
for i in range(1, n):
if array[i] <= array[dp[0]]:
dp[0] = i
elif array[dp[length]] < array[i]:
length += 1
dp[length] = i
parent[i] = dp[length - 1]
else:
curr_array = [array[dp[i]] for i in range(length)]
ceil = lower_bound(curr_array, array[i])
dp[ceil] = i
parent[i] = dp[ceil - 1]
ans = []

last_index = dp[length]
while last_index != -1:
ans[:0] = [array[last_index]]
last_index = parent[last_index]
return ans
34 changes: 32 additions & 2 deletions pydatastructs/linear_data_structures/tests/test_algorithms.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from pydatastructs import (
merge_sort_parallel, DynamicOneDimensionalArray,
OneDimensionalArray, brick_sort, brick_sort_parallel,
heapsort, matrix_multiply_parallel, counting_sort, bucket_sort, cocktail_shaker_sort, quick_sort, longest_common_subsequence,
is_ordered, upper_bound, lower_bound)
heapsort, matrix_multiply_parallel, counting_sort, bucket_sort,
cocktail_shaker_sort, quick_sort, longest_common_subsequence, is_ordered,
upper_bound, lower_bound, longest_increasing_subsequence)


from pydatastructs.utils.raises_util import raises
import random
Expand Down Expand Up @@ -241,3 +243,31 @@ def test_lower_bound():
output = lower_bound(arr8, 6, end=3, comp=lambda x, y: x > y)
expected_result = 1
assert expected_result == output

def test_longest_increasing_subsequence():
ODA = OneDimensionalArray

arr1 = ODA(int, [2, 5, 3, 7, 11, 8, 10, 13, 6])
output = longest_increasing_subsequence(arr1)
expected_result = [2, 3, 7, 8, 10, 13]
assert expected_result == output

arr2 = ODA(int, [3, 4, -1, 5, 8, 2, 2, 2, 3, 12, 7, 9, 10])
output = longest_increasing_subsequence(arr2)
expected_result = [-1, 2, 3, 7, 9, 10]
assert expected_result == output

arr3 = ODA(int, [6, 6, 6, 19, 9])
output = longest_increasing_subsequence(arr3)
expected_result = [6, 9]
assert expected_result == output

arr4 = ODA(int, [5, 4, 4, 3, 3, 6, 6, 8])
output = longest_increasing_subsequence(arr4)
expected_result = [3, 6, 8]
assert expected_result == output

arr5 = ODA(int, [7, 6, 6, 6, 5, 4, 3])
output = longest_increasing_subsequence(arr5)
expected_result = [3]
assert expected_result == output