Skip to content

Commit

Permalink
Enhancements to "Longest Increasing Subsequence" (#209)
Browse files Browse the repository at this point in the history
* perf(LongSubSeq): use pushfirst! instead of push! then reverse!

* refactor(LongSubSeq): generalize the lis methods to accept any Integer subtype

* test(LongSubSeq): test `lis` on all Integer subtypes

---------

Co-authored-by: Soc Virnyl S. Estela <[email protected]>
  • Loading branch information
digital-carver and uncomfyhalomacro authored Oct 26, 2023
1 parent b0a4123 commit b5269b4
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 13 deletions.
12 changes: 5 additions & 7 deletions src/longest_increasing_subsequence/binary_search.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
lis(arr::Array{Int}, ::Val{:bs})
lis(arr::Array{<:Integer}, ::Val{:bs})
# Arguments:
- `arr`: sequence of integers
Expand All @@ -23,12 +23,12 @@ https://cp-algorithms.com/sequences/longest_increasing_subsequence.html
- [Igor Malheiros](https://github.com/igormalheiros)
"""

function lis(arr::Array{Int}, ::Val{:bs})
function lis(arr::Array{T}, ::Val{:bs}) where T <: Integer
len = length(arr)
memo = ones(Int, len)
memo = ones(T, len)
p = ones(Int, len)

lis_arr = Int[]
lis_arr = T[]

len == 0 && return lis_arr # if `arr` is empty

Expand All @@ -48,12 +48,10 @@ function lis(arr::Array{Int}, ::Val{:bs})
last_pos = lis_len
for i in len:-1:1
if p[i] == last_pos
push!(lis_arr, arr[i])
pushfirst!(lis_arr, arr[i])
last_pos -= 1
end
end

reverse!(lis_arr)

return lis_arr
end
10 changes: 4 additions & 6 deletions src/longest_increasing_subsequence/dynamic_programming.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
lis(arr::Array{Int}, ::Val{:dp})
lis(arr::Array{<:Integer}, ::Val{:dp})
# Arguments:
- `arr`: sequence of integers
Expand All @@ -23,12 +23,12 @@ https://cp-algorithms.com/sequences/longest_increasing_subsequence.html
- [Igor Malheiros](https://github.com/igormalheiros)
"""

function lis(arr::Array{Int}, ::Val{:dp})
function lis(arr::Array{T}, ::Val{:dp}) where T <: Integer
len = length(arr)
memo = ones(Int, len)
p = zeros(Int, len)

lis_arr = Int[]
lis_arr = T[]

len == 0 && return lis_arr # if arr is empty

Expand All @@ -51,11 +51,9 @@ function lis(arr::Array{Int}, ::Val{:dp})

# Restoring
while lis_pos != 0
push!(lis_arr, arr[lis_pos])
pushfirst!(lis_arr, arr[lis_pos])
lis_pos = p[lis_pos]
end

reverse!(lis_arr)

return lis_arr
end
12 changes: 12 additions & 0 deletions test/longest_increasing_subsequence.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ using TheAlgorithms.LongSubSeq
# two possible results:
@test lis([3, 4, -1, 5, 8, 2, 3, 12, 7, 9, 10], Val(:dp)) in
[[-1, 2, 3, 7, 9, 10], [3, 4, 5, 8, 9, 10]]
# Boolean array
@test lis([true, false, false, true], Val(:dp)) == [false, true]
# other Integer subtypes
for T in [UInt128, UInt16, UInt32, UInt64, UInt8, BigInt, Int128, Int16, Int32, Int64, Int8]
@test lis(T[3, 10, 2, 1, 20], Val(:dp)) == T[3, 10, 20]
end
end

@testset "LIS: Binary Search approach!" begin
Expand All @@ -39,5 +45,11 @@ using TheAlgorithms.LongSubSeq
# two possible results:
@test lis([3, 4, -1, 5, 8, 2, 3, 12, 7, 9, 10], Val(:bs)) in
[[-1, 2, 3, 7, 9, 10], [3, 4, 5, 8, 9, 10]]
# Boolean array
@test lis([true, false, false, true], Val(:bs)) == [false, true]
# other Integer subtypes
for T in [UInt128, UInt16, UInt32, UInt64, UInt8, BigInt, Int128, Int16, Int32, Int64, Int8]
@test lis(T[3, 10, 2, 1, 20], Val(:bs)) == T[3, 10, 20]
end
end
end

0 comments on commit b5269b4

Please sign in to comment.