Given a number sequence, find the length of its Longest Incresing Subsequence (LIS).
In an increasing subsequence, all the elements are in increasing order (from lowest to highest).
====== Examples ======
Input: {4, 2, 3, 6, 10, 1, 12}
Output: 5
Explanation: The LIS is {2, 3, 6, 10, 12}
Input: {-4, 10, 3, 7, 15}
Output: 4
Explanation The LIS is {-4, 3, 7, 15}
Code:
def find_longest_incresing_subsequence_recursion(seq):
return find_longest_incresing_subsequence_recursion_util(seq, 0, -1)
def find_longest_incresing_subsequence_recursion_util(seq, current, prev):
if (current == len(seq)):
return 0
current_included_count = 0
if (prev == -1 or seq[current] >= seq[prev]):
current_included_count = 1 + find_longest_incresing_subsequence_recursion_util(seq, current + 1, current)
current_excluded_count = find_longest_incresing_subsequence_recursion_util(seq, current + 1, prev)
return max(current_included_count, current_excluded_count)
print("Recursive Method :")
print(find_longest_incresing_subsequence_recursion([4, 2, 3, 6, 10, 1, 12]))
print(find_longest_incresing_subsequence_recursion([-4, 10, 3, 7, 15]))
Output:
Recursive Method :
5
4
Complexity:
Code:
def find_longest_incresing_subsequence_dp_meomization(seq):
n = len(seq)
memory = [[0]*(n+1) for _ in range(n)]
return find_longest_incresing_subsequence_dp_meomization_util(seq, 0, -1, memory)
def find_longest_incresing_subsequence_dp_meomization_util(seq, current, prev, memory):
if (current == len(seq)):
return 0
if (memory[current][prev + 1]):
return memory[current][prev + 1]
current_included_count = 0
if (prev == -1 or seq[current] >= seq[prev]):
current_included_count = 1 + find_longest_incresing_subsequence_dp_meomization_util(seq, current + 1, current, memory)
current_excluded_count = find_longest_incresing_subsequence_dp_meomization_util(seq, current + 1, prev, memory)
memory[current][prev + 1] = max(current_included_count, current_excluded_count)
return memory[current][prev + 1]
print("\nDP -> Recursion + Memoization Method :")
print(find_longest_incresing_subsequence_dp_meomization([4, 2, 3, 6, 10, 1, 12]))
print(find_longest_incresing_subsequence_dp_meomization([-4, 10, 3, 7, 15]))
Output:
DP -> Recursion + Memoization Method :
5
4
Complexity:
Recursive Formula:
if num[i] > num[j] => dp[i] = dp[j] + 1 if there is no bigger LIS for i
Tabulation:
Final Table:
Code:
def find_longest_incresing_subsequence_dp_tabulation(nums):
n = len(nums)
table = [1] * n
for i in range(1, n):
for j in range(i):
if (nums[i] > nums[j]):
table[i] = max(table[i], table[j] + 1)
return table[i]
print("\nDP -> Iteration + Tabulation Method :")
print(find_longest_incresing_subsequence_dp_tabulation([4, 2, 3, 6, 10, 1, 12]))
print(find_longest_incresing_subsequence_dp_tabulation([-4, 10, 3, 7, 15]))
Output:
DP -> Iteration + Tabulation Method :
5
4
Complexity:
Given a number sequence, find the increasing subsequence with the higest sum.
====== Examples ======
Input: {4, 1, 2, 6, 10, 1, 12}
Output: 32
Explanation: The increasing subsequence is {4, 6, 10, 12}
Please note the difference, as the LIS is {1, 2, 6, 10, 12} with sum 31
Input: {-4, 10, 3, 7, 15}
Output: 25
Explanantion: The increasing subsequence are {10, 15} and {3, 7, 15}
Again the LIS is {-4, 3, 7, 15} with sum 21
Recursive Formula:
if num[i] > num[j] => dp[i] = dp[j] + 1 if there is no bigger MSIS for i
Tabulation:
Final Table:
Code:
def find_max_sum_incresing_subsequence_dp_tabulation(nums):
n = len(nums)
table = [num for num in nums]
for i in range(1, n):
for j in range(i):
if (nums[i] > nums[j]):
table[i] = max(table[i], table[j] + nums[i])
return table[i]
print("DP -> Iteration + Tabulation Method :")
print(find_max_sum_incresing_subsequence_dp_tabulation([4, 1, 2, 6, 10, 1, 12]))
print(find_max_sum_incresing_subsequence_dp_tabulation([-4, 10, 3, 7, 15]))
Output:
DP -> Iteration + Tabulation Method :
32
25
Complexity:
Given a number sequence, find the minimum number of elements that should be the deleted to make remaining sequence sorted.
====== Examples ======
Input: {4, 2, 3, 6, 10, 1, 12}
Output: 2
Explanation: We need to delete {4,1} to make remaining sequence {2, 3, 6, 10, 12} sorted
Input: {-4, 10, 3, 7, 15}
Output: 1
Explanation: We need to delete {10} to make remaining sequence {-4, 3, 7, 15} sorted
Input: {3, 2, 1, 0}
Output: 3
Explanation: Since sequence are in reverse order, need to delete all except one.
Code:
def min_deletions_required_to_sort_sequence_dp_tabulation(nums):
n = len(nums)
table = [1]*n
for i in range(1, n):
for j in range(i):
if (nums[i] > nums[j]):
table[i] = max(table[i], table[j] + 1)
print(f"Min deletions rquired to sort sequence : {n-table[i]}")
print("DP -> Iteration + Tabulation Method :")
min_deletions_required_to_sort_sequence_dp_tabulation([4, 2, 3, 6, 10, 1, 12])
min_deletions_required_to_sort_sequence_dp_tabulation([-4, 10, 3, 7, 15])
min_deletions_required_to_sort_sequence_dp_tabulation([3, 2, 1, 0])
Output:
DP -> Iteration + Tabulation Method :
Min deletions rquired to sort sequence : 2
Min deletions rquired to sort sequence : 1
Min deletions rquired to sort sequence : 3
Complexity:
Given a number sequence, find the length of its Longest Bitonic Subsequence(LBS).
A subsequence is considered bitonic if it is monotonically increasing and then monotonically decreasing.
====== Examples ======
Input: {4, 2, 3, 6, 10, 1, 12}
Output: 5
Explanation: The LBS is {2, 3, 6, 10, 1}
Input: {4, 2, 5, 9, 7, 6, 10, 3, 1}
Output: 7
Explanation: The LBS is {4, 5, 9, 7, 6, 3, 1}
Code:
def find_longest_bitonic_subsequence_dp_tabulation(nums):
n = len(nums)
table_lds_forward = [1] * n
table_lds_backward = [1] * n
# From beginning to end of sequence, calculate backward LDS
for i in range(1, n):
for j in range(i - 1, -1, -1):
if (nums[j] < nums[i]):
table_lds_backward[i] = max(table_lds_backward[i], table_lds_backward[j] + 1)
# From end to beginning of sequence, calculate forward LDS
for i in range(n - 2, -1, -1):
for j in range(i + 1, n):
if (nums[j] < nums[i]):
table_lds_forward[i] = max(table_lds_forward[i], table_lds_forward[j] + 1)
# Calculate max lbs length
max_lbs_length = 0
for i in range(n):
max_lbs_length = max(max_lbs_length, table_lds_backward[i] + table_lds_forward[i] - 1)
return max_lbs_length
print("DP -> Iteration + Tabulation Method :")
print(find_longest_bitonic_subsequence_dp_tabulation([4, 2, 3, 6, 10, 1, 12]))
print(find_longest_bitonic_subsequence_dp_tabulation([4, 2, 5, 9, 7, 6, 10, 3, 1]))
Output:
DP -> Iteration + Tabulation Method :
5
7
Complexity:
← Previous: Longest Common Substring Pattern
Next: Miscellaneous DP Problems →