Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • DSA
  • Interview Problems on DP
  • Practice DP
  • MCQs on DP
  • Tutorial on Dynamic Programming
  • Optimal Substructure
  • Overlapping Subproblem
  • Memoization
  • Tabulation
  • Tabulation vs Memoization
  • 0/1 Knapsack
  • Unbounded Knapsack
  • Subset Sum
  • LCS
  • LIS
  • Coin Change
  • Word Break
  • Egg Dropping Puzzle
  • Matrix Chain Multiplication
  • Palindrome Partitioning
  • DP on Arrays
  • DP with Bitmasking
  • Digit DP
  • DP on Trees
  • DP on Graph
Open In App
Next Article:
C++ Program for Longest Increasing Subsequence
Next article icon

C/C++ Program for Longest Increasing Subsequence

Last Updated : 28 Jun, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

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: 3
Explanation: The longest increasing subsequence is 3, 10, 20

Input: arr[] = {3, 2}
Output:1
Explanation: The longest increasing subsequences are {3} and {2}

Input: arr[] = {50, 3, 10, 7, 40, 80}
Output: 4
Explanation: The longest increasing subsequence is {3, 7, 40, 80}

Longest Increasing Sequence using Recursion:

The problem can be solved based on the following idea:

Let L(i) be the length of the LIS ending at index i such that arr[i] is the last element of the LIS. Then, L(i) can be recursively written as: 

  • L(i) = 1 + max(L(j) ) where 0 < j < i and arr[j] < arr[i]; or
  • L(i) = 1, if no such j exists.

Formally, the length of LIS ending at index i, is 1 greater than the maximum of lengths of all LIS ending at some index j such that arr[j] < arr[i] where j < i.

We can see that the above recurrence relation follows the optimal substructure property.

Below is the implementation of the recursive approach:

C++




// A Naive C++ recursive implementation
// of LIS problem
#include <bits/stdc++.h>
using namespace std;
 
// To make use of recursive calls, this
// function must return two things:
// 1) Length of LIS ending with element
// arr[n-1].
// We use max_ending_here for this purpose
// 2) Overall maximum as the LIS may end
// with an element before arr[n-1] max_ref
// is used this purpose.
// The value of LIS of full array of size
// n is stored in *max_ref which is
// our final result
int _lis(int arr[], int n, int* max_ref)
{
 
    // Base case
    if (n == 1)
        return 1;
 
    // 'max_ending_here' is length of
    // LIS ending with arr[n-1]
    int res, max_ending_here = 1;
 
    // Recursively get all LIS ending with
    // arr[0], arr[1] ... arr[n-2]. If
    // arr[i-1] is smaller than arr[n-1],
    // and max ending with arr[n-1] needs
    // to be updated, then update it
    for (int i = 1; i < n; i++) {
        res = _lis(arr, i, max_ref);
        if (arr[i - 1] < arr[n - 1]
            && res + 1 > max_ending_here)
            max_ending_here = res + 1;
    }
 
    // Compare max_ending_here with the
    // overall max. And update the
    // overall max if needed
    if (*max_ref < max_ending_here)
        *max_ref = max_ending_here;
 
    // Return length of LIS ending
    // with arr[n-1]
    return max_ending_here;
}
 
// The wrapper function for _lis()
int lis(int arr[], int n)
{
 
    // The max variable holds the result
    int max = 1;
 
    // The function _lis() stores its
    // result in max
    _lis(arr, n, &max);
 
    // Returns max
    return max;
}
 
// Driver program to test above function
int main()
{
    int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function call
    cout << "Length of lis is " << lis(arr, n);
    return 0;
}
 
 

C




// A Naive C recursive implementation
// of LIS problem
#include <stdio.h>
#include <stdlib.h>
 
// To make use of recursive calls, this
// function must return two things:
// 1) Length of LIS ending with element arr[n-1].
// We use max_ending_here for this purpose
// 2) Overall maximum as the LIS may end with
// an element before arr[n-1] max_ref is
//  used this purpose.
// The value of LIS of full array of size n
// is stored in *max_ref which is our final result
int _lis(int arr[], int n, int* max_ref)
{
    // Base case
    if (n == 1)
        return 1;
 
    // 'max_ending_here' is length of LIS
    // ending with arr[n-1]
    int res, max_ending_here = 1;
 
    // Recursively get all LIS ending with arr[0],
    // arr[1] ... arr[n-2]. If arr[i-1] is smaller
    // than arr[n-1], and max ending with arr[n-1]
    // needs to be updated, then update it
    for (int i = 1; i < n; i++) {
        res = _lis(arr, i, max_ref);
        if (arr[i - 1] < arr[n - 1]
            && res + 1 > max_ending_here)
            max_ending_here = res + 1;
    }
 
    // Compare max_ending_here with the overall
    // max. And update the overall max if needed
    if (*max_ref < max_ending_here)
        *max_ref = max_ending_here;
 
    // Return length of LIS ending with arr[n-1]
    return max_ending_here;
}
 
// The wrapper function for _lis()
int lis(int arr[], int n)
{
    // The max variable holds the result
    int max = 1;
 
    // The function _lis() stores its result in max
    _lis(arr, n, &max);
 
    // returns max
    return max;
}
 
// Driver program to test above function
int main()
{
    int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function call
    printf("Length of lis is %d", lis(arr, n));
    return 0;
}
 
 
Output
Length of lis is 5  

Complexity Analysis: 

  • Time Complexity: O(2n) The time complexity of this recursive approach is exponential as there is a case of overlapping subproblems as explained in the recursive tree diagram above.
  • Auxiliary Space: O(1). No external space is used for storing values apart from the internal stack space.

Longest Increasing Subsequence using Memoization:

If noticed carefully, we can see that the above recursive solution also follows the overlapping subproblems property i.e., same substructure solved again and again in different recursion call paths. We can avoid this using the memoization approach.

We can see that each state can be uniquely identified using two parameters:

  • Current index (denotes the last index of the LIS) and
  • Previous index (denotes the ending index of the previous LIS behind which the arr[i] is being concatenated).

Below is the implementation of the above approach.

C++




// C++ code of memoization approach for LIS
#include <bits/stdc++.h>
using namespace std;
 
// To make use of recursive calls, this
// function must return two things:
// 1) Length of LIS ending with element
// arr[n-1].
// We use max_ending_here for this purpose
// Overall maximum as the LIS may end with
// an element before arr[n-1] max_ref is
// used this purpose.
// The value of LIS of full array of size
// n is stored in *max_ref which is
// our final result
int f(int idx, int prev_idx, int n, int a[],
      vector<vector<int> >& dp)
{
    if (idx == n) {
        return 0;
    }
 
    if (dp[idx][prev_idx + 1] != -1) {
        return dp[idx][prev_idx + 1];
    }
 
    int notTake = 0 + f(idx + 1, prev_idx, n, a, dp);
    int take = INT_MIN;
    if (prev_idx == -1 || a[idx] > a[prev_idx]) {
        take = 1 + f(idx + 1, idx, n, a, dp);
    }
 
    return dp[idx][prev_idx + 1] = max(take, notTake);
}
 
// Function to find length of
// longest increasing subsequence
int longestSubsequence(int n, int a[])
{
    vector<vector<int> > dp(n + 1, vector<int>(n + 1, -1));
    return f(0, -1, n, a, dp);
}
 
// Driver program to test above function
int main()
{
    int a[] = { 3, 10, 2, 1, 20 };
    int n = sizeof(a) / sizeof(a[0]);
 
    // Function call
    cout << "Length of lis is " << longestSubsequence(n, a);
    return 0;
}
 
 
Output
Length of lis is 3  

Time Complexity: O(N2)
Auxiliary Space: O(N2)

Longest Increasing Subsequence using Dynamic Programming:

Because of the optimal substructure and overlapping subproblem property, we can also utilise Dynamic programming to solve the problem. Instead of memoization, we can use the nested loop to implement the recursive relation.

The outer loop will run from i = 1 to N and the inner loop will run from j = 0 to i and use the recurrence relation to solve the problem.

Below is the implementation of the above approach:  

C++




// Dynamic Programming C++ implementation
// of LIS problem
#include <bits/stdc++.h>
using namespace std;
 
// lis() returns the length of the longest
// increasing subsequence in arr[] of size n
int lis(int arr[], int n)
{
    int lis[n];
 
    lis[0] = 1;
 
    // Compute optimized LIS values in
    // bottom up manner
    for (int i = 1; i < n; i++) {
        lis[i] = 1;
        for (int j = 0; j < i; j++)
            if (arr[i] > arr[j] && lis[i] < lis[j] + 1)
                lis[i] = lis[j] + 1;
    }
 
    // Return maximum value in lis[]
    return *max_element(lis, lis + n);
}
 
// Driver program to test above function
int main()
{
    int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function call
    printf("Length of lis is %d\n", lis(arr, n));
    return 0;
}
 
 
Output
Length of lis is 5   

Time Complexity: O(N2) As a nested loop is used.
Auxiliary Space: O(N) Use of any array to store LIS values at each index.

Please Refer Longest Increasing Subsequence for detailed article.



Next Article
C++ Program for Longest Increasing Subsequence
author
kartik
Improve
Article Tags :
  • C Programs
  • C++ Programs
  • DSA
  • Dynamic Programming
  • LIS
Practice Tags :
  • Dynamic Programming

Similar Reads

  • C++ Program for Longest Increasing Subsequence
    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,
    9 min read
  • C++ Program for Longest Common Subsequence
    LCS Problem Statement: Given two sequences, find the length of longest subsequence present in both of them. A subsequence is a sequence that appears in the same relative order, but not necessarily contiguous. For example, "abc", "abg", "bdf", "aeg", '"acefg", .. etc are subsequences of "abcdefg". So
    3 min read
  • C Program for Longest Palindromic Subsequence | DP-12
    Given a sequence, find the length of the longest palindromic subsequence in it. As another example, if the given sequence is "BBABCBCAB", then the output should be 7 as "BABCBAB" is the longest palindromic subsequence in it. "BBBBB" and "BBCBB" are also palindromic subsequences of the given sequence
    3 min read
  • C++ Program for Longest subsequence of a number having same left and right rotation
    Given a numeric string S, the task is to find the maximum length of a subsequence having its left rotation equal to its right rotation. Examples: Input: S = "100210601" Output: 4 Explanation: The subsequence "0000" satisfies the necessary condition. The subsequence "1010" generates the string "0101"
    4 min read
  • C / C++ Program for Largest Sum Contiguous Subarray
    Write a C/C++ program for a given array arr[] of size N. The task is to find the sum of the contiguous subarray within a arr[] with the largest sum. Recommended: Please solve it on “PRACTICE ” first, before moving on to the solution. C / C++ Program for Largest Sum Contiguous Subarray using Kadane's
    5 min read
  • Find the longest subsequence of an array having LCM at most K
    Given an array arr[] of N elements and a positive integer K. The task is to find the longest sub-sequence in the array having LCM (Least Common Multiple) at most K. Print the LCM and the length of the sub-sequence, following the indexes (starting from 0) of the elements of the obtained sub-sequence.
    10 min read
  • C++ Program To Find Length Of The Longest Substring Without Repeating Characters
    Given a string str, find the length of the longest substring without repeating characters. For “ABDEFGABEF”, the longest substring are “BDEFGA” and "DEFGAB", with length 6.For “BBBB” the longest substring is “B”, with length 1.For "GEEKSFORGEEKS", there are two longest substrings shown in the below
    6 min read
  • C++ Program for Shortest Un-ordered Subarray
    An array is given of n length, and problem is that we have to find the length of shortest unordered {neither increasing nor decreasing} sub array in given array.Examples: Input : n = 5 7 9 10 8 11 Output : 3 Explanation : 9 10 8 unordered sub array. Input : n = 5 1 2 3 4 5 Output : 0 Explanation : A
    2 min read
  • C++ Program for Size of The Subarray With Maximum Sum
    An array is given, find length of the subarray having maximum sum. Examples : Input : a[] = {1, -2, 1, 1, -2, 1} Output : Length of the subarray is 2 Explanation: Subarray with consecutive elements and maximum sum will be {1, 1}. So length is 2 Input : ar[] = { -2, -3, 4, -1, -2, 1, 5, -3 } Output :
    4 min read
  • Maximum contiguous decreasing sequence obtained by removing any one element
    Given an array arr[] of N integers. The task is to find the length of the contiguous strictly decreasing sequence that can be derived after removing at most one element from the array arr[]. Examples Input: arr[] = {8, 7, 3, 5, 2, 9} Output: 4 Explanation: If we remove 3, The maximum length of decre
    10 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences