Longest Increasing Subsequence in given Linked List
Last Updated :
14 Feb, 2022
Given a sequence of numbers in the form of a linked list lis. Find the length of the Longest Increasing Subsequence(LIS) of the given Linked List.
Examples:
Input: list = 3->10->2->1->20
Output: 3
Explanation: The longest increasing subsequence is 3->10-> 20
Input: list = 3-> 2
Output: 1
Explanation: The longest increasing subsequence are 3 and 2
Input: list = 50->3->10->7->40->80
Output: Length of LIS = 4
Explanation: The longest increasing subsequence is {3->7->40->80} or {3->10->40->80}
Approach: The basic intuition of the solution is to start iterating from the first node to the end of linked list .In the process of moving calculate length of LIS ending at every node and store it in a count variable. Finally, calculate maximum count value among all nodes. Follow the steps mentioned below to solve the problem:
- Traverse the linked list from the starting node.
- LIS length of a linked list with one node is 1 .So we initialize every node count variable to 1.
- For every ith node traverse the first (i-1) nodes and do the following:
- if value of current node is greater than the value of previous node, extend sequence length.
- As maximum length ending with current node is required. select node from first (i-1) nodes which satisfy the previous condition and have maximum count value .
- Once all the nodes are traversed following the above procedure .find maximum count value among all nodes.
- The maximum count value is the required length of the LIS.
Below is the implementation of the above approach:
C++
// C++ program to find LIS on LinkedList
#include <bits/stdc++.h>
using namespace std;
// Structure of a node
class Node {
public:
int data;
struct Node* next;
// "count" variable is to keep track
// of LIS_LENGTH ending with
// that particular element
int count;
};
// Function to find the length of the LIS
int LIS(struct Node* head)
{
// If linked list is empty length is 0
if (head == NULL)
return 0;
// If linked list has only one node
// LIS length is 1
if (head->next == NULL)
return 1;
Node* curr_p = head->next;
// This loop calculates what is
// LIS_LENGTH ending with each and
// every node and stores in
// curr->count variable
while (curr_p != NULL) {
int maxi = 0;
Node* prev_p = head;
// This while loop traverse all nodes
// before curr_p and finds which node
// to extend so that maximum LIS
// length ending with curr_P can be
while (prev_p != curr_p) {
// Only extend if present data
// greater than previous value
if (curr_p->data
> prev_p->data) {
if (prev_p->count > maxi) {
maxi = prev_p->count;
}
}
prev_p = prev_p->next;
}
curr_p->count = 1 + maxi;
curr_p = curr_p->next;
}
int LIS_length = 0;
curr_p = head;
// Finding Maximum LIS_LENGTH
while (curr_p != NULL) {
if (LIS_length < curr_p->count) {
LIS_length = curr_p->count;
}
curr_p = curr_p->next;
}
return LIS_length;
}
// Function to push a node in linked list
void push(struct Node** head_ref,
int new_data)
{
// Allocate node
Node* new_node = new Node();
// Put in the data
new_node->data = new_data;
// Link the old list with the new node
new_node->next = (*head_ref);
// Assign count value to 1
new_node->count = 1;
// Move the head to point the new node
(*head_ref) = new_node;
}
// Driver code
int main()
{
// Start with the empty list
struct Node* head = NULL;
// Create a linked list
// Created linked list will be
// 3->10->2->1->20
push(&head, 20);
push(&head, 1);
push(&head, 2);
push(&head, 10);
push(&head, 3);
// Call LIS function which calculates
// LIS of Linked List
int ans = LIS(head);
cout << ans;
return 0;
}
Java
// Java program to find LIS on LinkedList
import java.util.*;
class GFG{
// Structure of a node
static class Node {
int data;
Node next;
// "count" variable is to keep track
// of LIS_LENGTH ending with
// that particular element
int count;
};
// Function to find the length of the LIS
static int LIS(Node head)
{
// If linked list is empty length is 0
if (head == null)
return 0;
// If linked list has only one node
// LIS length is 1
if (head.next == null)
return 1;
Node curr_p = head.next;
// This loop calculates what is
// LIS_LENGTH ending with each and
// every node and stores in
// curr.count variable
while (curr_p != null) {
int maxi = 0;
Node prev_p = head;
// This while loop traverse all nodes
// before curr_p and finds which node
// to extend so that maximum LIS
// length ending with curr_P can be
while (prev_p != curr_p) {
// Only extend if present data
// greater than previous value
if (curr_p.data
> prev_p.data) {
if (prev_p.count > maxi) {
maxi = prev_p.count;
}
}
prev_p = prev_p.next;
}
curr_p.count = 1 + maxi;
curr_p = curr_p.next;
}
int LIS_length = 0;
curr_p = head;
// Finding Maximum LIS_LENGTH
while (curr_p != null) {
if (LIS_length < curr_p.count) {
LIS_length = curr_p.count;
}
curr_p = curr_p.next;
}
return LIS_length;
}
// Function to push a node in linked list
static Node push(Node head_ref,
int new_data)
{
// Allocate node
Node new_node = new Node();
// Put in the data
new_node.data = new_data;
// Link the old list with the new node
new_node.next = head_ref;
// Assign count value to 1
new_node.count = 1;
// Move the head to point the new node
head_ref = new_node;
return head_ref;
}
// Driver code
public static void main(String[] args)
{
// Start with the empty list
Node head = null;
// Create a linked list
// Created linked list will be
// 3.10.2.1.20
head = push(head, 20);
head = push(head, 1);
head = push(head, 2);
head = push(head, 10);
head = push(head, 3);
// Call LIS function which calculates
// LIS of Linked List
int ans = LIS(head);
System.out.print(ans);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python code for the above approach
# Structure of a node
class Node:
def __init__(self, d):
self.data = d
self.next = None
self.count = 1
# "count" variable is to keep track
# of LIS_LENGTH ending with
# that particular element
# Function to find the length of the LIS
def LIS(head):
# If linked list is empty length is 0
if (head == None):
return 0
# If linked list has only one node
# LIS length is 1
if (head.next == None):
return 1
curr_p = head.next
# This loop calculates what is
# LIS_LENGTH ending with each and
# every node and stores in
# curr.count variable
while (curr_p != None):
maxi = 0
prev_p = head
# This while loop traverse all nodes
# before curr_p and finds which node
# to extend so that maximum LIS
# length ending with curr_P can be
while (prev_p != curr_p):
# Only extend if present data
# greater than previous value
if (curr_p.data > prev_p.data):
if (prev_p.count > maxi):
maxi = prev_p.count
prev_p = prev_p.next
curr_p.count = 1 + maxi
curr_p = curr_p.next
LIS_length = 0
curr_p = head
# Finding Maximum LIS_LENGTH
while (curr_p != None):
if (LIS_length < curr_p.count):
LIS_length = curr_p.count
curr_p = curr_p.next
return LIS_length
# Driver code
# Start with the empty list
# Create a linked list
# Created linked list will be
# 3->10->2->1->20
head = Node(3)
head.next = Node(10)
head.next.next = Node(2)
head.next.next.next = Node(1)
head.next.next.next.next = Node(20)
# Call LIS function which calculates
# LIS of Linked List
ans = LIS(head)
print(ans)
# This code is contributed by Saurabh Jaiswal
C#
// C# program to find LIS on List
using System;
using System.Collections.Generic;
public class GFG {
// Structure of a node
public class Node {
public int data;
public Node next;
// "count" variable is to keep track
// of LIS_LENGTH ending with
// that particular element
public int count;
};
// Function to find the length of the LIS
static int LIS(Node head)
{
// If linked list is empty length is 0
if (head == null)
return 0;
// If linked list has only one node
// LIS length is 1
if (head.next == null)
return 1;
Node curr_p = head.next;
// This loop calculates what is
// LIS_LENGTH ending with each and
// every node and stores in
// curr.count variable
while (curr_p != null) {
int maxi = 0;
Node prev_p = head;
// This while loop traverse all nodes
// before curr_p and finds which node
// to extend so that maximum LIS
// length ending with curr_P can be
while (prev_p != curr_p) {
// Only extend if present data
// greater than previous value
if (curr_p.data > prev_p.data) {
if (prev_p.count > maxi) {
maxi = prev_p.count;
}
}
prev_p = prev_p.next;
}
curr_p.count = 1 + maxi;
curr_p = curr_p.next;
}
int LIS_length = 0;
curr_p = head;
// Finding Maximum LIS_LENGTH
while (curr_p != null) {
if (LIS_length < curr_p.count) {
LIS_length = curr_p.count;
}
curr_p = curr_p.next;
}
return LIS_length;
}
// Function to push a node in linked list
static Node push(Node head_ref, int new_data)
{
// Allocate node
Node new_node = new Node();
// Put in the data
new_node.data = new_data;
// Link the old list with the new node
new_node.next = head_ref;
// Assign count value to 1
new_node.count = 1;
// Move the head to point the new node
head_ref = new_node;
return head_ref;
}
// Driver code
public static void Main(String[] args)
{
// Start with the empty list
Node head = null;
// Create a linked list
// Created linked list will be
// 3.10.2.1.20
head = push(head, 20);
head = push(head, 1);
head = push(head, 2);
head = push(head, 10);
head = push(head, 3);
// Call LIS function which calculates
// LIS of Linked List
int ans = LIS(head);
Console.Write(ans);
}
}
// This code is contributed by Rajput-Ji
JavaScript
<script>
// JavaScript code for the above approach
// Structure of a node
class Node {
constructor(d) {
this.data = d;
this.next = null;
this.count = 1;
}
// "count" variable is to keep track
// of LIS_LENGTH ending with
// that particular element
};
// Function to find the length of the LIS
function LIS(head)
{
// If linked list is empty length is 0
if (head == null)
return 0;
// If linked list has only one node
// LIS length is 1
if (head.next == null)
return 1;
let curr_p = head.next;
// This loop calculates what is
// LIS_LENGTH ending with each and
// every node and stores in
// curr.count variable
while (curr_p != null) {
let maxi = 0;
let prev_p = head;
// This while loop traverse all nodes
// before curr_p and finds which node
// to extend so that maximum LIS
// length ending with curr_P can be
while (prev_p != curr_p) {
// Only extend if present data
// greater than previous value
if (curr_p.data
> prev_p.data) {
if (prev_p.count > maxi) {
maxi = prev_p.count;
}
}
prev_p = prev_p.next;
}
curr_p.count = 1 + maxi;
curr_p = curr_p.next;
}
let LIS_length = 0;
curr_p = head;
// Finding Maximum LIS_LENGTH
while (curr_p != null) {
if (LIS_length < curr_p.count) {
LIS_length = curr_p.count;
}
curr_p = curr_p.next;
}
return LIS_length;
}
// Driver code
// Start with the empty list
// Create a linked list
// Created linked list will be
// 3->10->2->1->20
let head = new Node(3);
head.next = new Node(10);
head.next.next = new Node(2);
head.next.next.next = new Node(1);
head.next.next.next.next = new Node(20);
// Call LIS function which calculates
// LIS of Linked List
let ans = LIS(head);
document.write(ans);
// This code is contributed by Potta Lokesh
</script>
Time Complexity: O(N * N) where N is the length of the linked list
Auxiliary Space: O(N)
Similar Reads
Longest increasing sublist in a linked list Given a singly linked list and we want to count the elements that are continuously increasing and print the increasing linked list.Examples: Input : 8 -> 5 -> 7 -> 10 -> 9 -> 11 -> 12 -> 13 -> NULL Output : Number of continuously increasing elements = 4 Increasing linked list
11 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 increa
14 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 long
15+ min read
Length of longest increasing index dividing subsequence Given an array arr[] of size N, the task is to find the longest increasing sub-sequence such that index of any element is divisible by index of previous element (LIIDS). The following are the necessary conditions for the LIIDS:If i, j are two indices in the given array. Then: i < jj % i = 0arr[i]
7 min read
Longest Increasing Odd Even Subsequence Given an array of size n. The problem is to find the length of the subsequence in the given array such that all the elements of the subsequence are sorted in increasing order and also they are alternately odd and even. Note that the subsequence could start either with the odd number or with the even
8 min read