给定图中节点的最长递增序列的长度
给定一个图根,任务是找出图中最长递增序列的长度。
例子:
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
方法:给定的问题可以通过在图中的每个节点上使用深度优先搜索来解决。这个想法是使用递归并访问值小于当前节点的邻居节点,并在计算到当前节点的最长路径之前计算到邻居的最长路径。可以按照以下步骤解决问题:
- 在根节点上应用深度优先搜索以访问并将所有节点存储在列表中
- 使用递归在图的每个未访问节点上应用深度优先搜索,并使用哈希图将图映射的访问节点存储到到达该节点的最长路径
- 在每个节点遍历邻居的 ArrayList 并在值小于当前节点的值的邻居节点上使用递归,并计算以它们结束的最长路径
- 找到到邻居的最长路径的最大值并将其加 1 以计算到当前节点的最长路径
- 返回所有最长路径的最大值
下面是上述方法的实现:
C++
// C++ code for the above approach
#include
using namespace std;
class Node
{
public:
vector 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 &visited,
vector &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 &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 visited;
// List to store all the
// nodes in a graph
vector 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 *sevTeen = 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(sevTeen);
sevTeen->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 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 visited
= new HashMap<>();
// List to store all the
// nodes in a graph
List 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 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 visited,
List 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 sevTeen = 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(sevTeen);
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 neighbors;
public int val;
// constructor
public Node(int val)
{
this.val = val;
neighbors = new List();
}
}
// 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 visited
= new Dictionary();
// List to store all the
// nodes in a graph
List nodes = new List();
// 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 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 visited,
List 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 sevTeen = 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(sevTeen);
sevTeen.neighbors.Add(seven);
// Call the function
// and print the result
Console.WriteLine(
longestIncPath(seven));
}
}
// This code is contributed by 29AjayKumar
Javascript
输出
6
时间复杂度: O(V + E),其中 V 是顶点数,E 是边数
辅助空间: O(V)