C++ Program for Longest Increasing Subsequence
Last Updated :
04 Apr, 2023
The Longest Increasing Subsequence (LIS) problem is to find the length of the longest subsequence of a given sequence such that all elements of the subsequence are sorted in increasing order. For example, the length of LIS for {10, 22, 9, 33, 21, 50, 41, 60, 80} is 6 and LIS is {10, 22, 33, 50, 60, 80}.
Examples:
Input : arr[] = {3, 10, 2, 1, 20}
Output : Length of LIS = 3
The longest increasing subsequence is 3, 10, 20
Input : arr[] = {3, 2}
Output : Length of LIS = 1
The longest increasing subsequences are {3} and {2}
Input : arr[] = {50, 3, 10, 7, 40, 80}
Output : Length of LIS = 4
The longest increasing subsequence is {3, 7, 40, 80}
Overlapping Subproblems:
Considering the above implementation, the following is a recursion tree for an array of size 4. lis(n) gives us the length of LIS for arr[].
lis(4)
/ |
lis(3) lis(2) lis(1)
/ /
lis(2) lis(1) lis(1)
/
lis(1)
We can see that there are many subproblems that are solved again and again. So this problem has Overlapping Substructure property and recomputation of same subproblems can be avoided by either using Memoization or Tabulation. Following is a tabulated implementation for the LIS problem.
C++
#include <iostream>
using namespace std;
int lis( int arr[], int n)
{
int *lis, i, j, max = 0;
lis = ( int *) malloc ( sizeof ( int ) * n);
for (i = 0; i < n; i++)
lis[i] = 1;
for (i = 1; i < n; i++)
for (j = 0; j < i; j++)
if (arr[i] > arr[j] && lis[i] < lis[j] + 1)
lis[i] = lis[j] + 1;
for (i = 0; i < n; i++)
if (max < lis[i])
max = lis[i];
free (lis);
return max;
}
int main()
{
int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << "Length of lis is " << lis(arr, n);
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
int lis( int arr[], int n)
{
int *lis, i, j, max = 0;
lis = ( int *) malloc ( sizeof ( int ) * n);
for (i = 0; i < n; i++)
lis[i] = 1;
for (i = 1; i < n; i++)
for (j = 0; j < i; j++)
if (arr[i] > arr[j] && lis[i] < lis[j] + 1)
lis[i] = lis[j] + 1;
for (i = 0; i < n; i++)
if (max < lis[i])
max = lis[i];
free (lis);
return max;
}
int main()
{
int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };
int n = sizeof (arr) / sizeof (arr[0]);
printf ( "Length of lis is %d\n" , lis(arr, n));
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int lis( int [] arr, int n)
{
int max = 0 ;
int [] lst = new int [n];
Arrays.fill(lst, 1 );
for ( int i = 1 ; i < n; i++)
{
for ( int j = 0 ; j < i; j++)
{
if (arr[i] > arr[j] &&
lst[i] < lst[j] + 1 )
lst[i] = lst[j] + 1 ;
}
}
for ( int i = 0 ; i < n; i++)
if (max < lst[i])
max = lst[i];
return max;
}
public static void main(String[] args)
{
int [] arr = { 10 , 22 , 9 , 33 , 21 , 50 , 41 , 60 };
int n = arr.length;
System.out.println( "Length of lis is " +
lis(arr, n));
}
}
|
Python3
def lis(arr, n):
i, j, maxm = 0 , 0 , 0
lst = [ 1 for s in range (n)]
for i in range ( 1 , n):
for j in range ( 0 , i):
if (arr[i] > arr[j] and
lst[i] < lst[j] + 1 ):
lst[i] = lst[j] + 1
for i in range ( 0 , n):
if maxm < lst[i]:
maxm = lst[i]
return maxm
arr = [ 10 , 22 , 9 , 33 , 21 , 50 , 41 , 60 ]
n = len (arr)
print ( "Length of lst is" , lis(arr, n))
|
C#
using System;
public class GFG
{
static int lis( int [] arr, int n)
{
int max = 0;
int [] lst = new int [n];
Array.Fill(lst, 1);
for ( int i = 1; i < n; i++)
{
for ( int j = 0; j < i; j++)
{
if (arr[i] > arr[j] && lst[i] < lst[j] + 1)
{
lst[i] = lst[j] + 1;
}
}
}
for ( int i = 0; i < n; i++)
if (max < lst[i])
max = lst[i];
return max;
}
static public void Main ()
{
int [] arr = { 10, 22, 9, 33, 21, 50, 41, 60 };
int n = arr.Length;
Console.WriteLine( "Length of lis is " + lis(arr, n));
}
}
|
Javascript
<script>
function lis(arr,n)
{
let max = 0;
let lst = new Array(n);
for (let i=0;i<lst.length;i++)
{
lst[i]=1;
}
for (let i = 1; i < n; i++)
{
for (let j = 0; j < i; j++)
{
if (arr[i] > arr[j] &&
lst[i] < lst[j] + 1)
lst[i] = lst[j] + 1;
}
}
for (let i = 0; i < n; i++)
if (max < lst[i])
max = lst[i];
return max;
}
let arr=[10, 22, 9, 33, 21, 50, 41, 60 ];
let n = arr.length;
document.write( "Length of lis is " +
lis(arr, n));
</script>
|
Output:
Length of lis is 5
Complexity Analysis:
Time Complexity: O(n2). As nested loop is used.
Auxiliary Space: O(n).
Please refer complete article on Dynamic Programming | Set 3 (Longest Increasing Subsequence) for more details!
Method 2 : Lower Bound based approach
Algorithm :
1. Iterate the array.
2. Declare a new array ans to add the newly constructed increasing subsequence.
2. For every index, if lower_bound is points to the ending of the array ans, push it into a vector ans.
3. Return the ans array size.
C++
#include <bits/stdc++.h>
using namespace std;
int longest_increasing_subsequence(vector< int >& arr)
{
vector< int > ans;
int n = arr.size();
for ( int i = 0; i < n; i++) {
auto it
= lower_bound(ans.begin(), ans.end(), arr[i]);
if (it == ans.end()) {
ans.push_back(arr[i]);
}
else {
*it = arr[i];
}
}
return ans.size();
}
int main()
{
vector< int > a = { 10, 22, 9, 33, 21, 50, 41, 60 };
int ans = longest_increasing_subsequence(a);
cout << ans;
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int longestIncreasingSubsequence(List<Integer> arr) {
List<Integer> ans = new ArrayList<>();
int n = arr.size();
for ( int i = 0 ; i < n; i++) {
int it = arr.get(i);
int idx = Collections.binarySearch(ans, it);
if (idx < 0 ) {
idx = -(idx + 1 );
if (idx == ans.size()) {
ans.add(it);
} else {
ans.set(idx, it);
}
}
}
return ans.size();
}
public static void main(String[] args) {
List<Integer> a = Arrays.asList( 10 , 22 , 9 , 33 , 21 , 50 , 41 , 60 );
int ans = longestIncreasingSubsequence(a);
System.out.println(ans);
}
}
|
C#
using System;
using System.Collections.Generic;
public class Program {
public static int
LongestIncreasingSubsequence(List< int > arr)
{
List< int > ans = new List< int >();
List< int > prevIdx = new List< int >();
int n = arr.Count;
for ( int i = 0; i < n; i++) {
var it = ans.BinarySearch(arr[i]);
if (it < 0) {
it = ~it;
if (it == ans.Count) {
ans.Add(arr[i]);
prevIdx.Add(ans.Count - 2);
}
else {
ans[it] = arr[i];
prevIdx.Add(it == 0 ? -1
: prevIdx[it - 1]);
}
}
else {
prevIdx.Add(it == 0 ? -1 : prevIdx[it - 1]);
}
}
int len = ans.Count;
List< int > subseq = new List< int >();
int idx = len - 1;
while (idx >= 0) {
subseq.Add(ans[idx]);
idx = prevIdx[idx];
}
subseq.Reverse();
return len;
}
public static void Main()
{
List< int > a = new List< int >{ 10, 22, 9, 33,
21, 50, 41, 60 };
int ans = LongestIncreasingSubsequence(a);
Console.WriteLine(ans);
}
}
|
Time Complexity: O(nlogn) , n = size of array.
Space Complexity: O(n)
Share your thoughts in the comments
Please Login to comment...