Find Closest Node to Given Two Nodes

Updated on 29 May, 2025
Find Closest Node to Given Two Nodes header image

Problem Statement

In this problem, you are presented with a unique type of directed graph described by n nodes, where nodes are indexed from 0 to n-1. Each node is connected via a directed edge to at most one other node, as specified by an array edges. The array edges is 0-indexed where an element at index i gives the destination node of a directed edge from node i. If an element is -1, it indicates that the node at that index has no outgoing edges.

Given this graph setup and two specific nodes, node1 and node2, your task is to determine the index of a node that can be reached from both node1 and node2 such that the maximum distance to reach this node from either of the starting nodes is as small as possible. If multiple such nodes exist, the node with the smallest index should be returned. If it is not possible to find such a node, return -1. Note that the graph can have cycles, which may influence reaching a node and the computation of distances.

Examples

Example 1

Input:

edges = [2,2,3,-1], node1 = 0, node2 = 1

Output:

2

Explanation:

The distance from node 0 to node 2 is 1, and the distance from node 1 to node 2 is 1.
The maximum of those two distances is 1. It can be proven that we cannot get a node with a smaller maximum distance than 1, so we return node 2.

Example 2

Input:

edges = [1,2,-1], node1 = 0, node2 = 2

Output:

2

Explanation:

The distance from node 0 to node 2 is 2, and the distance from node 2 to itself is 0.
The maximum of those two distances is 2. It can be proven that we cannot get a node with a smaller maximum distance than 2, so we return node 2.

Constraints

  • n == edges.length
  • 2 <= n <= 105
  • -1 <= edges[i] < n
  • edges[i] != i
  • 0 <= node1, node2 < n

Approach and Intuition

When approaching this problem, a good understanding of graph traversal and shortest path algorithms is essential, as well as handling special cases involving directed cyclic graphs. Here’s a step-by-step breakdown of how we can approach finding the solution:

  1. Understand and visualize traveling from node1 and node2. Since each node leads to at most one other node:

    • Travel involves following a singular path until you reach a terminal node or cycle back to a previously visited node.
  2. Compute reachable nodes along with their distances from both node1 and node2:

    • Start at node1 and keep track of each node visited and the distance taken to reach it until you hit a node that either cycles or has no outgoing edges.
    • Repeat the process starting at node2.
  3. Identify nodes that can be reached from both node1 and node2:

    • Compare the sets of visited nodes from both starting points.
    • For nodes present in both sets, compute the maximum of the distances from the two starting nodes to these common nodes.
  4. Find the optimal node:

    • From the set of commonly reachable nodes, select the node with the smallest maximum distance.
    • If there are ties (multiple nodes with the same maximum distance), return the one with the smallest index.
    • If no common nodes are found, return -1.

This approach leverages straightforward graph traversal while keeping track of distances, making it efficient yet simple to implement given the graph’s constrained structure where each node links to at most one other node.

Solutions

  • C++
  • Java
cpp
class Solution {
public:
    void exploreGraph(int current, vector<int>& connections, vector<int>& distance, vector<bool>& visited) {
        visited[current] = true;
        int next = connections[current];
        if (next != -1 && !visited[next]) {
            distance[next] = 1 + distance[current];
            exploreGraph(next, connections, distance, visited);
        }
    }

    int findClosestNode(vector<int>& connections, int start1, int start2) {
        int sz = connections.size();
        vector<int> distance1(sz, numeric_limits<int>::max()), distance2(sz, numeric_limits<int>::max());
        vector<bool> seen1(sz), seen2(sz);
        distance1[start1] = 0, distance2[start2] = 0;

        exploreGraph(start1, connections, distance1, seen1);
        exploreGraph(start2, connections, distance2, seen2);

        int closestNode = -1, minimumDistance = numeric_limits<int>::max();
        for (int i = 0; i < sz; i++) {
            if (minimumDistance > max(distance1[i], distance2[i])) {
                closestNode = i;
                minimumDistance = max(distance1[i], distance2[i]);
            }
        }

        return closestNode;
    }
};

This C++ solution efficiently identifies the closest node to two given nodes in a directed graph represented as a list of connections, where each index and its value portray a directional connection from index to value.

  • Initiate by defining the exploreGraph function to explore the graph and compute the distance from the starting node to all other nodes using simple DFS. This function updates the distance array with the number of steps taken to reach each node and uses a visited array to keep track of explored nodes.
  • Proceed to define the findClosestNode function:
    1. Prepare two distance vectors distance1 and distance2, initializing them with maximum integer values. These arrays will store the minimal distances from the two start nodes defined by start1 and start2.
    2. Two boolean vectors seen1 and seen2 are used to record if a node has been visited starting from start1 and start2.
    3. Call exploreGraph for both start nodes to fill out the distance1 and distance2 arrays.
    4. Initialize closestNode to -1 to indicate that no node has been found initially. Iterate over all nodes. For each node, determine the greater of the two distances (max(distance1[i], distance2[i])). Update the closestNode with the node index if this maximum is less than the previously recorded minimum distance.
    5. Eventually, return the closestNode which represents the node that has the shortest largest distance to both start nodes.

This implementation excels in clarity and scalability, effectively capturing both single-path distances and identifying optimal node accessibility in the context of varying graph topologies.

java
class GraphTraversal {
    public void depthFirstSearch(int vertex, int[] connections, int[] pathLength, Boolean[] visited) {
        visited[vertex] = true;
        int next = connections[vertex];
        if (next != -1 && !visited[next]) {
            pathLength[next] = pathLength[vertex] + 1;
            depthFirstSearch(next, connections, pathLength, visited);
        }
    }

    public int findClosestNode(int[] connections, int start1, int start2) {
        int totalVertices = connections.length;
        int[] path1 = new int[totalVertices], path2 = new int[totalVertices];
        Arrays.fill(path1, Integer.MAX_VALUE);
        Arrays.fill(path2, Integer.MAX_VALUE);
        path1[start1] = 0;
        path2[start2] = 0;

        Boolean[] visited1 = new Boolean[totalVertices], visited2 = new Boolean[totalVertices];
        Arrays.fill(visited1, Boolean.FALSE);
        Arrays.fill(visited2, Boolean.FALSE);

        depthFirstSearch(start1, connections, path1, visited1);
        depthFirstSearch(start2, connections, path2, visited2);

        int minIndex = -1, minDistance = Integer.MAX_VALUE;
        for (int i = 0; i < totalVertices; i++) {
            if (minDistance > Math.max(path1[i], path2[i])) {
                minIndex = i;
                minDistance = Math.max(path1[i], path2[i]);
            }
        }

        return minIndex;
    }
}

This Java program helps find the closest node between two given nodes within a graph represented by an adjacency list. The solution utilizes a Depth-First Search (DFS) approach to determine the shortest path lengths from each starting node to all other nodes in the graph. Here’s how the provided solution operates:

  • DepthFirstSearch Method:

    • Initialize each traversal with the start vertex marked as visited.
    • Explore all connected vertices recursively.
    • Keep tracking the path length from the start vertex to the current vertex, updating the shortest path found.
  • FindClosestNode Method:

    • Set up initial conditions, marking path lengths from the start nodes to infinite (except to themselves where it's 0) and marking all nodes as unvisited.
    • Conduct individual depth-first searches starting from each of the two given nodes.
    • Post DFS, evaluate each vertex in the graph to find the vertex that has the smallest maximum distance from either start node.

The outcome is an integer representing the index of the closest node to the two given start nodes, minimizing the longest path from either start node. This solution efficiently maps out paths to determine the most centrally located vertex relative to the two specified starting nodes, leveraging DFS to handle potentially complex connection scenarios in the graph.

Comments

No comments yet.