0

I am trying to implement leetcode allpaths problem I have written the below solution, which is giving me the wrong output, I have purposefully, left the console statements for better debugging. Basically the variable path does not gets updated to [0] whenever the recursive call to findPath is done.

What am I missing here?

const allPaths = (edges) => {
  const graph = buildAdjacencyListGraph(edges);
  console.log(graph);
  const result = []
  let path = [0];
  findPath(graph, 0, edges.length - 1, result, path)
}

const findPath = (graph, src, dest, result, path) => {
  for (let neighbor of graph[src]) {
    console.log('Path before push: ', path);
    console.log('Result before push: ', result);
    path.push(neighbor);
    console.log('Path: ', path);
    console.log('Result: ', result);
    console.log('Neighbor', neighbor);
    console.log('Destination: ', dest);
    console.log('Is neighbor and dest equal?: ', dest === neighbor);
    if (neighbor === dest) {
      result.push([...path])
      console.log('Result after equal: ', result);
      path = [0];
      console.log('Path after equal: ', path);
      continue;
    }
    findPath(graph, neighbor, dest, result, path);
  }
}

const buildAdjacencyListGraph = (edges) => {
  const graph = {};

  for (let [i, edge] of edges.entries()) {
    graph[i] = edge;
  }
  return graph;
}
const graph = [[4,3,1],[3,2,4],[3],[4],[]]

allPaths(graph)

1 Answers1

0

There are a few issues:

  • allPaths does not have a return statement. It should end with return result.

  • After result.push([...path]) it is wrong to reset the path with path = [0]. The path should only return to its previous state, so that from there alternative continuations can be explored. With setting it to [0], the next iteration of the loop may add a node to that path that has no connection from 0 at all.

  • After the recursive call is made, the path should return to its previous state before doing the next iteration, as we don't want to keep the current neighbor there, adding the next neighbor after it. No, the next neighbor should replace the current neighbor in the path.

Not a real problem, but the adjacency list you create is really unnecessary. What you get is already an adjacency list, where it is a list of lists instead of a dict of lists. But since the keys are 0..n-1, it really is used in the same way. You can just skip that conversion.

So with these corrections, the code becomes:

const allPaths = (edges) => {
  // no need for calling buildAdjacencyListGraph
  const result = [];
  findPath(edges, 0, edges.length - 1, result, []); // no need for path variable
  return result;
}

const findPath = (graph, src, dest, result, path) => {
  for (let neighbor of graph[src]) {
    path.push(neighbor);
    if (neighbor === dest) {
      result.push([...path]);
    } else {
      findPath(graph, neighbor, dest, result, path);
    }
    path.pop(); // backtrack!
  }
}
trincot
  • 317,000
  • 35
  • 244
  • 286