Printing Longest Increasing Subsequence (LIS)
Last Updated : 07 May, 2025
Given a sequence of numbers, the task is to find and print the Longest Increasing Subsequence (LIS), the longest subsequence where each element is strictly greater than the previous one. If multiple LIS of the same maximum length exist, we must select the one that appears first based on the lexicographical order of their indices (i.e., the earliest combination of positions from the original sequence). The goal is to ensure both maximum length and the earliest possible subsequence.
Examples:
Input: [10, 20, 3, 40]
Output : 10 20 40
Explanation: [10, 20, 40]
is the longest subsequence where each number is greater than the previous one, maintaining the original order
Input: [10, 22, 9, 33, 21, 50, 41, 60, 80]
Output : 10 22 33 50 60 80
Explanation: There are multiple longest Increasing subsequence of length 6, examples [10, 22, 33, 50, 60, 80] and [10 22 33 41 60 80]. The first one has lexicographic smallest order.
[Naive Approach]: Dynamic programming with Subsequence Storage – O(n^3) Time and O(n^2) Space
We extend the of bottom-up DP solution of LIS problem. Please remember, for every element arr[i]
, it iterates over all previous elements (arr[prev]
where prev < i
) to find the longest subsequence that can be extended by arr[i]. To find elements of LIS, w
e build an array of arrays, L such that L[i] stores LIS of arr that ends with arr[i]. For example, for array [3, 2, 6, 4, 5, 1].
L[0] = [3]
L[1] = [2]
L[2] = [2, 6]
L[3] = [2, 4]
L[4] = [2, 4, 5]
L[5] = [1]
The final result is the longest subsequence among all L[i].
Step by step Approach
- Create an array of arrays
L
where L[i]
stores the longest increasing subsequence (LIS) ending at index i
. - Initialize
L[0]
with the first element (arr[0]
), as it’s the only subsequence possible at this point. - For each element
arr[i]
(starting from i=1
to n-1
):- Check all previous indices
prev
(from 0
to i-1
). - If
arr[i] > arr[prev]
(valid to extend the subsequence) and the subsequence L[prev]
is longer than the current best for L[i]
: Update L[i]
by copying L[prev]
(this extends the subsequence ending at prev
). - Append
arr[i]
to L[i]
(since arr[i]
is the endpoint of this subsequence).
- After processing all elements, iterate through
L[0]
to L[n-1]
to find the longest subsequence in L
, which is the LIS.
C++ #include <iostream> #include <vector> using namespace std; // Function to construct and print Longest // Increasing Subsequence vector<int> getLIS(vector<int>& arr){ // L[i] - The longest increasing // sub-sequence ends with arr[i] int n = arr.size(); vector<vector<int>> L(n); // L[0] is equal to arr[0] L[0].push_back(arr[0]); // Start from index 1 for (int i = 1; i < n; i++){ int lis = 1; // Do for every prev less than i for (int prev = 0; prev < i; prev++){ /* L[i] = {Max(L[prev])} + arr[i] where prev < i and arr[prev] < arr[i] */ if ((arr[i] > arr[prev]) && (lis < L[prev].size() + 1)) { // Copy the vector of prev and update lis of i L[i] = L[prev]; lis = L[prev].size() + 1; } } // L[i] ends with arr[i] L[i].push_back(arr[i]); } // L[i] now stores increasing sub-sequence // of arr[0..i] that ends with arr[i] vector<int> res = L[0]; // LIS will be max of all increasing // sub-sequences of arr for (vector<int> x : L) if (x.size() > res.size()) res = x; return res; } // Driver function int main(){ vector<int> arr = {10, 20, 3, 40}; vector<int> max_lis = getLIS(arr); for (int x : max_lis) cout << x << " "; return 0; }
Java import java.util.ArrayList; import java.util.List; class GfG { // Function to construct and print Longest // Increasing Subsequence static ArrayList<Integer> getLIS(int arr[]) { int n = arr.length; // L[i] - The longest increasing subsequence ending with arr[i] List<List<Integer>> L = new ArrayList<>(); // Initialize L[i] as empty lists for (int i = 0; i < n; i++) { L.add(new ArrayList<>()); } // Base case: first element L.get(0).add(arr[0]); // Build the LIS lists for (int i = 1; i < n; i++) { int lis = 1; for (int prev = 0; prev < i; prev++) { if (arr[i] > arr[prev] && lis < L.get(prev).size() + 1) { L.set(i, new ArrayList<>(L.get(prev))); lis = L.get(prev).size() + 1; } } L.get(i).add(arr[i]); } // Find the list with the maximum length ArrayList<Integer> res = new ArrayList<>(L.get(0)); for (List<Integer> x : L) { if (x.size() > res.size()) { res = new ArrayList<>(x); } } return res; } // Driver function public static void main(String[] args) { int[] arr = {10, 20, 3, 40}; ArrayList<Integer> max_lis = getLIS(arr); for (int i = 0; i < max_lis.size(); i++) { System.out.print(max_lis.get(i) + " "); } } }
Python def getLIS(arr): n = len(arr) # L[i] - The longest increasing sub-sequence ends with arr[i] L = [[] for _ in range(n)] # L[0] is equal to arr[0] L[0].append(arr[0]) # Start from index 1 for i in range(1, n): lis = 1 # Do for every prev less than i for prev in range(i): if arr[i] > arr[prev] and lis < len(L[prev]) + 1: # Copy the list of prev and update lis of i L[i] = L[prev][:] lis = len(L[prev]) + 1 # L[i] ends with arr[i] L[i].append(arr[i]) # L[i] now stores increasing sub-sequence # of arr[0..i] that ends with arr[i] res = L[0] # LIS will be max of all increasing # sub-sequences of arr for x in L: if len(x) > len(res): res = x # return the longest increasing subsequence return res # Driver function if __name__ == "__main__": arr = [10, 20, 3, 40] # Construct and print LIS of arr max_lis = getLIS(arr) print(" ".join(map(str, max_lis)))
C# using System; using System.Collections.Generic; class GfG { // Function to construct and return the Longest Increasing Subsequence static List<int> getLIS(int[] arr) { int n = arr.Length; // L[i] - The longest increasing subsequence ending with arr[i] List<List<int>> L = new List<List<int>>(n); // Initialize the lists for (int i = 0; i < n; i++) { L.Add(new List<int>()); } // Base case: first element L[0].Add(arr[0]); // Build the LIS lists for (int i = 1; i < n; i++) { int lis = 1; for (int prev = 0; prev < i; prev++) { if (arr[i] > arr[prev] && lis < L[prev].Count + 1) { // Copy the best previous subsequence L[i] = new List<int>(L[prev]); lis = L[prev].Count + 1; } } // Append current element L[i].Add(arr[i]); } // Find the list with the maximum length List<int> res = new List<int>(L[0]); foreach (List<int> x in L) { if (x.Count > res.Count) { res = x; } } return res; } // Driver function static void Main(){ int[] arr = {10, 20, 3, 40 }; List<int> max_lis = getLIS(arr); foreach (int x in max_lis){ Console.Write(x + " "); } Console.WriteLine(); } }
JavaScript // Function to construct and print Longest // Increasing Subsequence function getLIS(arr) { const n = arr.length; // L[i] - The longest increasing sub-sequence // ends with arr[i] const L = Array.from({ length: n }, () => []); // L[0] is equal to arr[0] L[0].push(arr[0]); // Start from index 1 for (let i = 1; i < n; i++) { let lis = 1; // Do for every prev less than i for (let prev = 0; prev < i; prev++) { if (arr[i] > arr[prev] && lis < L[prev].length + 1) { // Copy the list of prev and update lis of i L[i] = [...L[prev]]; lis = L[prev].length + 1; } } // L[i] ends with arr[i] L[i].push(arr[i]); } // L[i] now stores increasing sub-sequence // of arr[0..i] that ends with arr[i] let res = L[0]; // LIS will be max of all increasing // sub-sequences of arr for (const x of L) { if (x.length > res.length) { res = x; } } // Return the longest increasing subsequence return res; } // Driver function const arr = [10, 20, 3, 40]; let max_lis = getLIS(arr); console.log(max_lis.join(' '));
Time Complexity: O(n3), n2 for two nested loops and n for copying another vector in a vector (e.g. : L[i] = L[prev]) contributes O(n) also.
Space Complexity: O(n2), 2d vector to store our LIS
[Better Approach]: Dynamic programming with Single 1D Extra Array – O(n^2) Time and O(n) Space
In the previous solution, we use an array of arrays to store all subsequences ending with every index. The idea here is to store only indexes of only the previous item in the answer LIS.
- We use an array seq[] to store indexes of previous items in LIS and used to construct the resultant sequence. Along with constructing dp[] array, we fill indexes in seq[].
- After filling seq[] and dp[], we find the index of the largest element in dp.
- Now using the index found in step 2 and seq[], we construct the result sequence.
C++ #include <iostream> #include <vector> #include <algorithm> using namespace std; // Function to find the longest increasing // subsequence. vector<int> getLIS(vector<int>& arr) { int n = arr.size(); // Initialize dp array with 1. vector<int> dp(n, 1); // Initialize hash array with index values. // We store previous indexs in LIS here vector<int> seq(n); for (int i = 0; i < n; i++) { seq[i] = i; // Mark element itself as prev for (int prev = 0; prev < i; prev++) { // Update dp and hash values if // condition satisfies. if (arr[prev] < arr[i] && 1 + dp[prev] > dp[i]) { dp[i] = 1 + dp[prev]; seq[i] = prev; } } } // Now we find the last element // in LIS using dp[] int ans = -1; int ansInd = -1; for (int i = 0; i < n; i++) { if (dp[i] > ans) { ans = dp[i]; ansInd = i; } } // Now construct result sequence using seq[] // and ans_ind vector<int> res; res.push_back(arr[ansInd]); while (seq[ansInd] != ansInd) { ansInd = seq[ansInd]; res.push_back(arr[ansInd]); } reverse(res.begin(), res.end()); return res; } int main() { vector<int> arr = {10, 20, 3, 40}; vector<int> max_lis = getLIS(arr); for (int num : max_lis) { cout << num << " "; } cout << endl; return 0; }
Java import java.util.ArrayList; import java.util.Collections; public class Main { // Function to find the longest increasing subsequence public static ArrayList<Integer> getLIS(int[] arr) { int n = arr.length; // Initialize dp array with 1 int[] dp = new int[n]; for (int i = 0; i < n; i++) { dp[i] = 1; } // Initialize seq array with index values (to store previous indices in LIS) int[] seq = new int[n]; for (int i = 0; i < n; i++) { seq[i] = i; } // Compute dp and seq arrays for (int i = 0; i < n; i++) { for (int prev = 0; prev < i; prev++) { if (arr[prev] < arr[i] && 1 + dp[prev] > dp[i]) { dp[i] = 1 + dp[prev]; seq[i] = prev; } } } // Find the index of the last element in the LIS int ans = -1; int ansInd = -1; for (int i = 0; i < n; i++) { if (dp[i] > ans) { ans = dp[i]; ansInd = i; } } // Construct the result sequence using seq array ArrayList<Integer> res = new ArrayList<>(); res.add(arr[ansInd]); while (seq[ansInd] != ansInd) { ansInd = seq[ansInd]; res.add(arr[ansInd]); } // Reverse the result to get the correct order Collections.reverse(res); return res; } public static void main(String[] args) { int[] arr = {10, 20, 3, 40}; ArrayList<Integer> max_lis = getLIS(arr); for (int i = 0; i < max_lis.size(); i++) { System.out.print(max_lis.get(i) + " "); } } }
Python # Function to find the longest increasing subsequence def getLIS(arr): n = len(arr) # Initialize dp array with 1 dp = [1] * n # Initialize seq array with index values (to store previous indices in LIS) seq = list(range(n)) # Compute dp and seq arrays for i in range(n): for prev in range(i): if arr[prev] < arr[i] and 1 + dp[prev] > dp[i]: dp[i] = 1 + dp[prev] seq[i] = prev # Find the index of the last element in the LIS ans = -1 ans_ind = -1 for i in range(n): if dp[i] > ans: ans = dp[i] ans_ind = i # Construct the result sequence using seq array res = [] res.append(arr[ans_ind]) while seq[ans_ind] != ans_ind: ans_ind = seq[ans_ind] res.append(arr[ans_ind]) # Reverse the result to get the correct order res.reverse() return res if __name__ == "__main__": arr = [10, 20, 3, 40] max_lis = getLIS(arr) print(" ".join(map(str, max_lis)))
C# using System; using System.Collections.Generic; class GfG{ // Function to find the longest increasing subsequence static List<int> getLIS(int[] arr){ int n = arr.Length; // Initialize dp array with 1 int[] dp = new int[n]; for (int i = 0; i < n; i++) { dp[i] = 1; } // Initialize seq array with index values (to store previous indices in LIS) int[] seq = new int[n]; for (int i = 0; i < n; i++) { seq[i] = i; } // Compute dp and seq arrays for (int i = 0; i < n; i++) { for (int prev = 0; prev < i; prev++) { if (arr[prev] < arr[i] && 1 + dp[prev] > dp[i]) { dp[i] = 1 + dp[prev]; seq[i] = prev; } } } // Find the index of the last element in the LIS int ans = -1; int ansInd = -1; for (int i = 0; i < n; i++) { if (dp[i] > ans) { ans = dp[i]; ansInd = i; } } // Construct the result sequence using seq array List<int> res = new List<int>(); res.Add(arr[ansInd]); while (seq[ansInd] != ansInd) { ansInd = seq[ansInd]; res.Add(arr[ansInd]); } // Reverse the result to get the correct order res.Reverse(); return res; } static void Main(string[] args) { int[] arr = {10, 20, 3, 40}; List<int> max_lis = getLIS(arr); Console.WriteLine(string.Join(" ", max_lis)); } }
JavaScript // Function to find the longest increasing subsequence function getLIS(arr) { const n = arr.length; // Initialize dp array with 1 const dp = new Array(n).fill(1); // Initialize seq array with index values (to store previous indices in LIS) const seq = [...Array(n).keys()]; // Compute dp and seq arrays for (let i = 0; i < n; i++) { for (let prev = 0; prev < i; prev++) { if (arr[prev] < arr[i] && 1 + dp[prev] > dp[i]) { dp[i] = 1 + dp[prev]; seq[i] = prev; } } } // Find the index of the last element in the LIS let ans = -1; let ansInd = -1; for (let i = 0; i < n; i++) { if (dp[i] > ans) { ans = dp[i]; ansInd = i; } } // Construct the result sequence using seq array const res = []; res.push(arr[ansInd]); while (seq[ansInd] !== ansInd) { ansInd = seq[ansInd]; res.push(arr[ansInd]); } // Reverse the result to get the correct order res.reverse(); return res; } const arr = [10, 20, 3, 40]; const max_lis = getLIS(arr); console.log(max_lis.join(" "));
Time Complexity: O(n2), We have two nested loops: one to fill the dp[]
array and another to backtrack using the seq[]
array.
Space Complexity: O(n), We use two arrays, dp[]
and seq[]
, each of size n.
[Expected Approach] Using DP with Binary Search – O(n*log(n)) Time and O(n) Space
The idea is based on LIS using binary search to improve efficiency. We maintain a list (dp
) representing the minimum possible last value for increasing subsequences of different lengths. We process elements backward and use negative values to flip the problem into a decreasing order, making it easier to find the correct position using binary search function like lower_bound(
) in C++. Tracking previous indices allows us to reconstruct the actual sequence after processing. This method ensures both maximum length and earliest lexicographical order efficiently.
Step by Step Approach
- Create an empty list
dp
to store pairs (-value, index)
. - Create a map
prv
to remember the previous index for each element. - Iterate from the last element to the first.
- For each element, take its negative (
ve = -arr[ix]
) to handle increasing order via decreasing values. - Use binary search (
lower_bound
) to find the right position in dp
. - If the position is at the end of
dp
, append the element and set its previous index. - Else, update
dp[i]
with the current value and set its previous link. - Start from the last element’s index (from
dp.back().second
). - Follow previous pointers (
prv[cur]
) to collect elements into the result list. - Since we built the sequence backward, finally reverse the
ret
array to get the LIS in correct order.
C++ #include <iostream> #include <vector> #include <algorithm> #include <unordered_map> using namespace std; vector<int> getLIS(int N, vector<int>& arr) { vector<pair<int, int>> dp; unordered_map<int, int> prv; // Process array in reverse order for (int ix = N - 1; ix >= 0; --ix) { int ve = -arr[ix]; // Binary search to find insertion point auto it = lower_bound(dp.begin(), dp.end(), make_pair(ve, 0), [](const pair<int, int>& a, const pair<int, int>& b) { return a.first < b.first; }); int tmp = -1; // Default previous index int i = distance(dp.begin(), it); if (i == dp.size()) { if (!dp.empty()) { tmp = dp.back().second; } dp.emplace_back(ve, ix); } else { if (i > 0) { tmp = dp[i-1].second; } dp[i] = {ve, ix}; } prv[ix] = tmp; } // Reconstruct the LIS vector<int> ret; int cur = dp.back().second; while (cur >= 0) { ret.push_back(arr[cur]); cur = prv[cur]; } return ret; } int main() { vector<int> arr = {10, 20, 3, 40}; vector<int> lis = getLIS(arr.size(), arr); for (int num : lis) { cout << num << " "; } return 0; }
Java import java.util.*; public class Solution { // Function to find Longest Increasing Subsequence static ArrayList<Integer> getLIS(int arr[]) { ArrayList<Integer> ret = new ArrayList<>(); ArrayList<int[]> dp = new ArrayList<>(); HashMap<Integer, Integer> prv = new HashMap<>(); int N = arr.length; // Process array in reverse order for (int ix = N - 1; ix >= 0; --ix) { // Using negative for bisect_left equivalent int ve = -arr[ix]; // Binary search to find insertion point int l = 0, r = dp.size(); while (l < r) { int m = l + (r - l) / 2; if (dp.get(m)[0] < ve) { l = m + 1; } else { r = m; } } int i = l; int tmp = -1; if (i == dp.size()) { if (!dp.isEmpty()) { tmp = dp.get(dp.size() - 1)[1]; } dp.add(new int[]{ve, ix}); } else { if (i > 0) { tmp = dp.get(i - 1)[1]; } dp.set(i, new int[]{ve, ix}); } prv.put(ix, tmp); } // Reconstruct the LIS int cur = dp.get(dp.size() - 1)[1]; while (cur >= 0) { ret.add(arr[cur]); cur = prv.getOrDefault(cur, -1); } return ret; } public static void main(String[] args) { int[] arr = {10, 20, 3, 40}; ArrayList<Integer> lis = getLIS(arr); System.out.println(lis); } }
Python def getLIS(arr): ret = [] dp = [] prv = {} N = len(arr) # Process array in reverse order for ix in range(N - 1, -1, -1): # Using negative for bisect_left equivalent ve = -arr[ix] # Binary search to find insertion point l, r = 0, len(dp) while l < r: m = l + (r - l) // 2 if dp[m][0] < ve: l = m + 1 else: r = m i = l # Default previous index tmp = -1 if i == len(dp): if dp: tmp = dp[-1][1] dp.append((ve, ix)) else: if i > 0: tmp = dp[i - 1][1] dp[i] = (ve, ix) prv[ix] = tmp # Reconstruct the LIS cur = dp[-1][1] while cur >= 0: ret.append(arr[cur]) cur = prv.get(cur, -1) return ret # Example usage arr = [10, 20, 3, 40] print(getLIS(arr))
C# using System; using System.Collections.Generic; public class Solution { // Function to find Longest Increasing Subsequence public List<int> getLIS(List<int> arr) { List<int> ret = new List<int>(); List<(int, int)> dp = new List<(int, int)>(); // Stores (-value, index) pairs Dictionary<int, int> prv = new Dictionary<int, int>(); // Stores previous index for each element int N = arr.Count; // Process array in reverse order for (int ix = N - 1; ix >= 0; --ix) { int ve = -arr[ix]; // Binary search to find insertion point int l = 0, r = dp.Count; while (l < r) { int m = l + (r - l) / 2; if (dp[m].Item1 < ve) { l = m + 1; } else { r = m; } } int i = l; // Default previous index int tmp = -1; if (i == dp.Count) { if (dp.Count > 0) { tmp = dp[dp.Count - 1].Item2; } dp.Add((ve, ix)); } else { if (i > 0) { tmp = dp[i - 1].Item2; } dp[i] = (ve, ix); } prv[ix] = tmp; } // Reconstruct the LIS int cur = dp[dp.Count - 1].Item2; while (cur >= 0) { ret.Add(arr[cur]); cur = prv.ContainsKey(cur) ? prv[cur] : -1; } return ret; } public static void Main(string[] args) { List<int> arr = new List<int> {10, 20, 3, 40}; Solution sol = new Solution(); List<int> lis = sol.getLIS(arr); Console.WriteLine(string.Join(" ", lis)); } }
JavaScript function getLIS(arr) { let ret = []; let dp = []; let prv = {}; let N = arr.length; // Process array in reverse order for (let ix = N - 1; ix >= 0; --ix) { let ve = -arr[ix]; // Binary search to find insertion point let l = 0, r = dp.length; while (l < r) { let m = l + Math.floor((r - l) / 2); if (dp[m][0] < ve) { l = m + 1; } else { r = m; } } let i = l; // Default previous index let tmp = -1; if (i === dp.length) { if (dp.length > 0) { tmp = dp[dp.length - 1][1]; } dp.push([ve, ix]); } else { if (i > 0) { tmp = dp[i - 1][1]; } dp[i] = [ve, ix]; } prv[ix] = tmp; } // Reconstruct the LIS let cur = dp[dp.length - 1][1]; while (cur >= 0) { ret.push(arr[cur]); cur = prv[cur] !== undefined ? prv[cur] : -1; } return ret; } // Driver Code const arr = [10, 20, 3, 40]; console.log(getLIS(arr));
Time Complexity: O(N log N) ,for each of the N elements we perform a binary search (using lower_bound
) in the dp
array, which takes O(log N) time. Thus, processing all elements gives an overall complexity of O(N log N).
Auxiliary space: O(N), we use extra space for the dp
list and the prv
map, both of which at most store one entry per element in the input array.
Similar Reads
Printing Longest Increasing Subsequence (LIS)
Given a sequence of numbers, the task is to find and print the Longest Increasing Subsequence (LIS), the longest subsequence where each element is strictly greater than the previous one. If multiple LIS of the same maximum length exist, we must select the one that appears first based on the lexicogr
15+ min read
Longest Increasing Subsequence (LIS)
Given an array arr[] of size n, the task is to find the length of the Longest Increasing Subsequence (LIS) i.e., the longest possible subsequence in which the elements of the subsequence are sorted in increasing order. Examples: Input: arr[] = [3, 10, 2, 1, 20]Output: 3Explanation: The longest incre
14 min read
Printing longest Increasing consecutive subsequence
Given n elements, write a program that prints the longest increasing subsequence whose adjacent element difference is one. Examples: Input : a[] = {3, 10, 3, 11, 4, 5, 6, 7, 8, 12} Output : 3 4 5 6 7 8 Explanation: 3, 4, 5, 6, 7, 8 is the longest increasing subsequence whose adjacent element differs
8 min read
Printing Longest Bitonic Subsequence
The Longest Bitonic Subsequence problem is to find the longest subsequence of a given sequence such that it is first increasing and then decreasing. A sequence, sorted in increasing order is considered Bitonic with the decreasing part as empty. Similarly, decreasing order sequence is considered Bito
12 min read
Longest Increasing Subsequence Size (N log N)
Given an array arr[] of size N, the task is to find the length of the Longest Increasing Subsequence (LIS) i.e., the longest possible subsequence in which the elements of the subsequence are sorted in increasing order, in O(N log N). Examples: Input: arr[] = {3, 10, 2, 1, 20}Output: 3Explanation: Th
9 min read
Printing Longest Common Subsequence
Given two sequences, print the longest subsequence present in both of them. Examples: LCS for input Sequences âABCDGHâ and âAEDFHRâ is âADHâ of length 3. LCS for input Sequences âAGGTABâ and âGXTXAYBâ is âGTABâ of length 4.We have discussed Longest Common Subsequence (LCS) problem in a previous post
15+ min read
Minimizing and Maximizing longest Increasing Subsequence (LIS)
Given a string S of length n-1, consisting of characters '<' and '>' only. The ith character is the comparison result between the ith element and the (i+1)th element of the sequence. If the ith character of the string is '<', then the ith element of the sequence is less than the (i+1)st ele
9 min read
Length of longest increasing subsequence in a string
Given a string S, the task is to find the length of the longest increasing subsequence present in the given string. A sequence of characters placed in increasing order of their ASCII values is called an increasing sequence. Examples: Input: S = "abcfgffs"Output: 6Explanation: Subsequence "abcfgs" is
7 min read
Longest Common Increasing Subsequence (LCS + LIS)
Given two arrays, a[] and b[], find the length of the longest common increasing subsequence(LCIS). LCIS refers to a subsequence that is present in both arrays and strictly increases.Prerequisites: LCS, LIS. Examples: Input: a[] = [3, 4, 9, 1], b[] = [5, 3, 8, 9, 10, 2, 1]Output: 2Explanation: The lo
15+ min read
Printing Maximum Sum Increasing Subsequence
The Maximum Sum Increasing Subsequence problem is to find the maximum sum subsequence of a given sequence such that all elements of the subsequence are sorted in increasing order. Examples: Input: [1, 101, 2, 3, 100, 4, 5]Output: [1, 2, 3, 100]Input: [3, 4, 5, 10]Output: [3, 4, 5, 10]Input: [10, 5,
15 min read