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, 12Input: 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++ 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 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# 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 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. |
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 |
6
Time Complexity: O(V + E), where V is the number of vertices and E is the number of edges
Auxiliary Space: O(V)