Open In App

Length of Longest increasing sequence of nodes in a given Graph

Last Updated : 04 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a graph root, the task is to find the length of the longest increasing sequence in the graph.

Example:

Input:   root =     7—-17
                         /    \
        1—-2—-5      4
             /          \      \
          11           6—-8
                               /
                            12
Output: 6 
Explanation: The longest increasing sequence in the graph consists of the nodes 1, 2, 5, 6, 8, 12

Input:   2
           /  \
        3     1
      /         \
    5           6
Output: 4

 

Approach: The given problem can be solved by using the depth-first search on every node in the graph. The idea is to use recursion and visit the neighbor nodes with values less than the current node and calculate the longest path ending up to the neighbors before calculating the longest path ending up to the current node. Below steps can be followed to solve the problem:

  • Apply depth-first search on the root node to visit and store all the nodes in a list
  • Use recursion to apply depth-first search on every unvisited node of the graph and use a hashmap to store the visited nodes of the graph mapping to the longest path ending up to that node
    • At every node iterate through the ArrayList of neighbors and use recursion on the neighbor nodes with a value less than the current node’s value and calculate the longest path ending at them
    • Find the maximum of the longest path ending up to the neighbors and add 1 to it for calculating the longest path ending up to the current node
  • Return the maximum of all longest paths

Below is the implementation of the above approach:

C++




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
 
class Node {
public:
    vector<Node*> neighbors;
    int val;
 
    // constructor
    Node(int v)
    {
 
        val = v;
        neighbors = {};
    }
};
 
// Depth first search function to add
// every node of the graph in a list
void dfs(Node* root, unordered_map<Node*, int>& visited,
         vector<Node*>& nodes)
{
 
    // If the current node is
    // already visited then return
    if (visited.find(root) != visited.end())
        return;
 
    // Mark the current node as visited
    visited[root] = 0;
 
    // Add the current node in the list
    nodes.push_back(root);
 
    // Iterate through all neighbors
    for (Node* n : root->neighbors) {
 
        // Visit the neighbors
        dfs(n, visited, nodes);
    }
}
// Depth first search function
// to calculate the longest path
// ending at every node
int findLongestPath(Node* root,
                    unordered_map<Node*, int>& visited)
{
 
    // If the current node is visited
    // then return its value
    if (visited[root] > 0)
        return visited[root];
 
    // Initialize a variable max to
    // calculate longest increasing path
    int maxi = 0;
 
    // Iterate through all neighbors
    for (Node* n : root->neighbors) {
 
        // If neighbor's value is less
        // than current node's value then
        // find longest path ending up to
        // the neighbor
        if (n->val < root->val) {
 
            // Update max
            maxi = max(maxi, findLongestPath(n, visited));
        }
    }
 
    // Store the value in the hashmap
    visited[root] = maxi + 1;
 
    // Return the longest increasing
    // path ending on root
    return maxi + 1;
}
// Function to find the longest
// increasing path in a graph
int longestIncPath(Node* root)
{
 
    // Base case
    if (root == NULL)
        return 0;
 
    // Initialize a variable max
    // to calculate longest path
    int maxi = 1;
 
    // Initialize a HashMap to
    // store the visited nodes
    unordered_map<Node*, int> visited;
 
    // List to store all the
    // nodes in a graph
    vector<Node*> nodes;
 
    // Apply DFS on the graph
    // add all the nodes in a list
    dfs(root, visited, nodes);
 
    // Iterate through the list of nodes
    for (int i = 0; i < nodes.size(); i++) {
 
        Node* curr = nodes[i];
 
        // Current node is not already visited
        if (visited[curr] == 0) {
 
            // Apply DFS to find the
            // longest path ending on
            // the current node
            findLongestPath(curr, visited);
        }
 
        // Update max by comparing it
        // with the longest path ending
        // on the current node
        maxi = max(maxi, visited[curr]);
    }
 
    // Return the answer
    return maxi;
}
 
// Driver code
int main()
{
 
    // Initialize the graph
    Node* seven = new Node(7);
    Node* five = new Node(5);
    Node* four = new Node(4);
    Node* seventeen = new Node(17);
    Node* one = new Node(1);
    Node* two = new Node(2);
    Node* six = new Node(6);
    Node* eight = new Node(8);
    Node* eleven = new Node(11);
    Node* twelve = new Node(12);
    one->neighbors.push_back(two);
    eleven->neighbors.push_back(two);
    two->neighbors.push_back(one);
    two->neighbors.push_back(eleven);
    two->neighbors.push_back(five);
    eight->neighbors.push_back(twelve);
    eight->neighbors.push_back(six);
    eight->neighbors.push_back(four);
    four->neighbors.push_back(eight);
    four->neighbors.push_back(seven);
    twelve->neighbors.push_back(eight);
    six->neighbors.push_back(five);
    six->neighbors.push_back(eight);
    five->neighbors.push_back(two);
    five->neighbors.push_back(seven);
    five->neighbors.push_back(six);
    seven->neighbors.push_back(five);
    seven->neighbors.push_back(four);
    seven->neighbors.push_back(seventeen);
    seventeen->neighbors.push_back(seven);
 
    // Call the function
    // and print the result
    cout << (longestIncPath(seven));
    return 0;
}
 
// This code is contributed by Potta Lokesh


Java




// Java implementation for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    static class Node {
 
        List<Node> neighbors;
        int val;
 
        // constructor
        public Node(int val)
        {
 
            this.val = val;
            neighbors = new ArrayList<>();
        }
    }
 
    // Function to find the longest
    // increasing path in a graph
    public static int longestIncPath(Node root)
    {
 
        // Base case
        if (root == null)
            return 0;
 
        // Initialize a variable max
        // to calculate longest path
        int max = 1;
 
        // Initialize a HashMap to
        // store the visited nodes
        Map<Node, Integer> visited = new HashMap<>();
 
        // List to store all the
        // nodes in a graph
        List<Node> nodes = new ArrayList<>();
 
        // Apply DFS on the graph
        // add all the nodes in a list
        dfs(root, visited, nodes);
 
        // Iterate through the list of nodes
        for (int i = 0; i < nodes.size(); i++) {
 
            Node curr = nodes.get(i);
 
            // Current node is not already visited
            if (visited.get(curr) == 0) {
 
                // Apply DFS to find the
                // longest path ending on
                // the current node
                findLongestPath(curr, visited);
            }
 
            // Update max by comparing it
            // with the longest path ending
            // on the current node
            max = Math.max(max, visited.get(curr));
        }
 
        // Return the answer
        return max;
    }
 
    // Depth first search function
    // to calculate the longest path
    // ending at every node
    public static int
    findLongestPath(Node root, Map<Node, Integer> visited)
    {
 
        // If the current node is visited
        // then return its value
        if (visited.get(root) > 0)
            return visited.get(root);
 
        // Initialize a variable max to
        // calculate longest increasing path
        int max = 0;
 
        // Iterate through all neighbors
        for (Node n : root.neighbors) {
 
            // If neighbor's value is less
            // than current node's value then
            // find longest path ending up to
            // the neighbor
            if (n.val < root.val) {
 
                // Update max
                max = Math.max(max,
                               findLongestPath(n, visited));
            }
        }
 
        // Store the value in the hashmap
        visited.put(root, max + 1);
 
        // Return the longest increasing
        // path ending on root
        return max + 1;
    }
 
    // Depth first search function to add
    // every node of the graph in a list
    public static void dfs(Node root,
                           Map<Node, Integer> visited,
                           List<Node> nodes)
    {
 
        // If the current node is
        // already visited then return
        if (visited.containsKey(root))
            return;
 
        // Mark the current node as visited
        visited.put(root, 0);
 
        // Add the current node in the list
        nodes.add(root);
 
        // Iterate through all neighbors
        for (Node n : root.neighbors) {
 
            // Visit the neighbors
            dfs(n, visited, nodes);
        }
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        // Initialize the graph
        Node seven = new Node(7);
        Node five = new Node(5);
        Node four = new Node(4);
        Node seventeen = new Node(17);
        Node one = new Node(1);
        Node two = new Node(2);
        Node six = new Node(6);
        Node eight = new Node(8);
        Node eleven = new Node(11);
        Node twelve = new Node(12);
        one.neighbors.add(two);
        eleven.neighbors.add(two);
        two.neighbors.add(one);
        two.neighbors.add(eleven);
        two.neighbors.add(five);
        eight.neighbors.add(twelve);
        eight.neighbors.add(six);
        eight.neighbors.add(four);
        four.neighbors.add(eight);
        four.neighbors.add(seven);
        twelve.neighbors.add(eight);
        six.neighbors.add(five);
        six.neighbors.add(eight);
        five.neighbors.add(two);
        five.neighbors.add(seven);
        five.neighbors.add(six);
        seven.neighbors.add(five);
        seven.neighbors.add(four);
        seven.neighbors.add(seventeen);
        sevTeen.neighbors.add(seven);
 
        // Call the function
        // and print the result
        System.out.println(longestIncPath(seven));
    }
}


C#




// C# implementation for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
    class Node {
 
        public List<Node> neighbors;
        public int val;
 
        // constructor
        public Node(int val)
        {
 
            this.val = val;
            neighbors = new List<Node>();
        }
    }
 
    // Function to find the longest
    // increasing path in a graph
    static int longestIncPath(Node root)
    {
 
        // Base case
        if (root == null)
            return 0;
 
        // Initialize a variable max
        // to calculate longest path
        int max = 1;
 
        // Initialize a Dictionary to
        // store the visited nodes
        Dictionary<Node, int> visited
            = new Dictionary<Node, int>();
 
        // List to store all the
        // nodes in a graph
        List<Node> nodes = new List<Node>();
 
        // Apply DFS on the graph
        // add all the nodes in a list
        dfs(root, visited, nodes);
 
        // Iterate through the list of nodes
        for (int i = 0; i < nodes.Count; i++) {
 
            Node curr = nodes[i];
 
            // Current node is not already visited
            if (visited[curr] == 0) {
 
                // Apply DFS to find the
                // longest path ending on
                // the current node
                findlongestPath(curr, visited);
            }
 
            // Update max by comparing it
            // with the longest path ending
            // on the current node
            max = Math.Max(max, visited[curr]);
        }
 
        // Return the answer
        return max;
    }
 
    // Depth first search function
    // to calculate the longest path
    // ending at every node
    static int
    findlongestPath(Node root,
                    Dictionary<Node, int> visited)
    {
 
        // If the current node is visited
        // then return its value
        if (visited[root] > 0)
            return visited[root];
 
        // Initialize a variable max to
        // calculate longest increasing path
        int max = 0;
 
        // Iterate through all neighbors
        foreach(Node n in root.neighbors)
        {
 
            // If neighbor's value is less
            // than current node's value then
            // find longest path ending up to
            // the neighbor
            if (n.val < root.val) {
 
                // Update max
                max = Math.Max(max,
                               findlongestPath(n, visited));
            }
        }
 
        // Store the value in the hashmap
        if (visited.ContainsKey(root))
            visited[root] = max + 1;
        else
            visited.Add(root, max + 1);
 
        // Return the longest increasing
        // path ending on root
        return max + 1;
    }
 
    // Depth first search function to add
    // every node of the graph in a list
    static void dfs(Node root,
                    Dictionary<Node, int> visited,
                    List<Node> nodes)
    {
 
        // If the current node is
        // already visited then return
        if (visited.ContainsKey(root))
            return;
 
        // Mark the current node as visited
        visited.Add(root, 0);
 
        // Add the current node in the list
        nodes.Add(root);
 
        // Iterate through all neighbors
        foreach(Node n in root.neighbors)
        {
 
            // Visit the neighbors
            dfs(n, visited, nodes);
        }
    }
 
    // Driver code
    public static void Main(String[] args)
    {
 
        // Initialize the graph
        Node seven = new Node(7);
        Node five = new Node(5);
        Node four = new Node(4);
        Node seventeen = new Node(17);
        Node one = new Node(1);
        Node two = new Node(2);
        Node six = new Node(6);
        Node eight = new Node(8);
        Node eleven = new Node(11);
        Node twelve = new Node(12);
        one.neighbors.Add(two);
        eleven.neighbors.Add(two);
        two.neighbors.Add(one);
        two.neighbors.Add(eleven);
        two.neighbors.Add(five);
        eight.neighbors.Add(twelve);
        eight.neighbors.Add(six);
        eight.neighbors.Add(four);
        four.neighbors.Add(eight);
        four.neighbors.Add(seven);
        twelve.neighbors.Add(eight);
        six.neighbors.Add(five);
        six.neighbors.Add(eight);
        five.neighbors.Add(two);
        five.neighbors.Add(seven);
        five.neighbors.Add(six);
        seven.neighbors.Add(five);
        seven.neighbors.Add(four);
        seven.neighbors.Add(seventeen);
        seventeen.neighbors.Add(seven);
 
        // Call the function
        // and print the result
        Console.WriteLine(longestIncPath(seven));
    }
}
 
// This code is contributed by 29AjayKumar


Javascript




// Javascript code for the above approach
 
class Node {
  // constructor
  constructor(v) {
 
    this.val = v;
    this.neighbors = [];
  }
};
 
// Depth first search function to add
// every node of the graph in a list
function dfs(root, visited, nodes) {
 
  // If the current node is
  // already visited then return
  if (visited.has(root))
    return;
 
  // Mark the current node as visited
  visited.set(root, 0);
 
  // Add the current node in the list
  nodes.push(root);
 
  // Iterate through all neighbors
  for (n of root.neighbors) {
 
    // Visit the neighbors
    dfs(n, visited, nodes);
  }
}
// Depth first search function
// to calculate the longest path
// ending at every node
function findLongestPath(root, visited) {
 
  // If the current node is visited
  // then return its value
  if (visited.get(root) > 0)
    return visited.get(root);
 
  // Initialize a variable max to
  // calculate longest increasing path
  let maxi = 0;
 
  // Iterate through all neighbors
  for (n of root.neighbors) {
 
    // If neighbor's value is less
    // than current node's value then
    // find longest path ending up to
    // the neighbor
    if (n.val < root.val) {
 
      // Update max
      maxi = Math.max(
        maxi,
        findLongestPath(n, visited));
    }
  }
 
  // Store the value in the hashmap
  visited.set(root, maxi + 1);
 
  // Return the longest increasing
  // path ending on root
  return maxi + 1;
}
// Function to find the longest
// increasing path in a graph
function longestIncPath(root) {
 
  // Base case
  if (root == null)
    return 0;
 
  // Initialize a variable max
  // to calculate longest path
  let maxi = 1;
 
  // Initialize a HashMap to
  // store the visited nodes
  let visited = new Map();
 
  // List to store all the
  // nodes in a graph
  let nodes = [];
 
  // Apply DFS on the graph
  // add all the nodes in a list
  dfs(root, visited, nodes);
 
  // Iterate through the list of nodes
  for (let i = 0; i < nodes.length; i++) {
 
    let curr = nodes[i];
 
    // Current node is not already visited
    if (visited.get(curr) == 0) {
 
      // Apply DFS to find the
      // longest path ending on
      // the current node
      findLongestPath(curr, visited);
    }
 
    // Update max by comparing it
    // with the longest path ending
    // on the current node
    maxi = Math.max(
      maxi, visited.get(curr));
  }
 
  // Return the answer
  return maxi;
}
 
// Driver code
 
 
// Initialize the graph
let seven = new Node(7);
let five = new Node(5);
let four = new Node(4);
let seventeen = new Node(17);
let one = new Node(1);
let two = new Node(2);
let six = new Node(6);
let eight = new Node(8);
let eleven = new Node(11);
let twelve = new Node(12);
one.neighbors.push(two);
eleven.neighbors.push(two);
two.neighbors.push(one);
two.neighbors.push(eleven);
two.neighbors.push(five);
eight.neighbors.push(twelve);
eight.neighbors.push(six);
eight.neighbors.push(four);
four.neighbors.push(eight);
four.neighbors.push(seven);
twelve.neighbors.push(eight);
six.neighbors.push(five);
six.neighbors.push(eight);
five.neighbors.push(two);
five.neighbors.push(seven);
five.neighbors.push(six);
seven.neighbors.push(five);
seven.neighbors.push(four);
seven.neighbors.push(seventeen);
seventeen.neighbors.push(seven);
 
// Call the function
// and print the result
document.write((longestIncPath(seven)));
 
// This code is contributed by saurabh_jaiswal.


Python3




from typing import List
 
 
class Node:
    def __init__(self, v):
        self.neighbors = []
        self.val = v
 
 
def dfs(root: Node, visited: dict, nodes: List[Node]) -> None:
    if root in visited:
        return
    visited[root] = 0
    nodes.append(root)
    for n in root.neighbors:
        dfs(n, visited, nodes)
 
 
def findLongestPath(root: Node, visited: dict) -> int:
    if root in visited and visited[root] > 0:
        return visited[root]
    maxi = 0
    for n in root.neighbors:
        if n.val < root.val:
            maxi = max(maxi, findLongestPath(n, visited))
    visited[root] = maxi + 1
    return maxi + 1
 
 
def longestIncPath(root: Node) -> int:
    if root is None:
        return 0
    maxi = 1
    visited = {}
    nodes = []
    dfs(root, visited, nodes)
    for curr in nodes:
        if visited[curr] == 0:
            findLongestPath(curr, visited)
        maxi = max(maxi, visited[curr])
    return maxi
 
 
# Driver code
if __name__ == '__main__':
    seven = Node(7)
    five = Node(5)
    four = Node(4)
    seventeen = Node(17)
    one = Node(1)
    two = Node(2)
    six = Node(6)
    eight = Node(8)
    eleven = Node(11)
    twelve = Node(12)
    one.neighbors.append(two)
    eleven.neighbors.append(two)
    two.neighbors.extend([one, eleven, five])
    eight.neighbors.extend([twelve, six, four])
    four.neighbors.extend([eight, seven])
    twelve.neighbors.append(eight)
    six.neighbors.extend([five, eight])
    five.neighbors.extend([two, seven, six])
    seven.neighbors.extend([five, four, seventeen])
    seventeen.neighbors.append(seven)
    print(longestIncPath(seven))
 
# This code is contributed by Akash Jha


Output

6

Time Complexity: O(V + E), where V is the number of vertices and E is the number of edges
Auxiliary Space: O(V)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads