Skip to content

Commit aa4cd6d

Browse files
committed
feat: Solve bfs shortest reach
- Hackerrank
1 parent 9f2c3db commit aa4cd6d

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed

graphs/bfs-shortest-reach.js

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/**
2+
* Hackerrank
3+
* Consider an undirected graph where each edge is the same weight. Each of the
4+
* nodes is labeled consecutively. You will be given a number of queries. For
5+
* each query, you will be given a list of edges describing an undirected graph.
6+
* After you create a representation of the graph, you must determine and report
7+
* the shortest distance to each of the other nodes from a given starting
8+
* position using the breadth-first search algorithm (BFS). Distances are to be
9+
* reported in node number order, ascending. If a node is unreachable, print -1
10+
* for that node. Each of the edges weighs 6 units of distance.
11+
*
12+
* Constraints:
13+
* 1. 1 <= Q <= 10
14+
* 2. 2 <= n <= 1000
15+
* 3. 1 <= m <= (n*(n-1)) / 2
16+
* 4. 1 <= u,v,s <= n
17+
*
18+
* This solution got 55 points
19+
* Problem link: http://hr.gs/fdaaad
20+
*/
21+
22+
// Complete the bfs function below.
23+
function bfs(n, m, edges, s) {
24+
const EDGE_WEIGHT = 6;
25+
const graph = buildGraph(edges);
26+
const start = graph.get(s);
27+
const distances = Array(n).fill(-1);
28+
29+
/* Edge case - Start node is not connected to any other node.
30+
* In that case, not perfom the BFS
31+
*/
32+
if (start) {
33+
const queue = new LinkedList(new LinkedListNode(start));
34+
distances[start.id - 1] = 0;
35+
while (queue.size > 0) {
36+
const node = queue.poll().data;
37+
node.neighbors.forEach(neighbor => {
38+
if (distances[neighbor.id - 1] === -1) {
39+
distances[neighbor.id - 1] = distances[node.id - 1] + EDGE_WEIGHT;
40+
queue.insert(new LinkedListNode(neighbor));
41+
}
42+
});
43+
}
44+
}
45+
46+
distances.splice(s - 1, 1);
47+
return distances;
48+
}
49+
50+
/**
51+
* Build the graph based on the edges array representation
52+
* @param {number[][]} edges - Array of graph edges
53+
*/
54+
function buildGraph(edges) {
55+
const graph = new Map();
56+
edges.forEach(edge => {
57+
const firstNodeId = edge[0];
58+
const secondNodeId = edge[1];
59+
60+
let firstNode;
61+
if (!graph.has(firstNodeId)) {
62+
firstNode = new Node(firstNodeId);
63+
graph.set(firstNodeId, firstNode);
64+
} else {
65+
firstNode = graph.get(firstNodeId);
66+
}
67+
68+
let secondNode;
69+
if (!graph.has(secondNodeId)) {
70+
secondNode = new Node(secondNodeId);
71+
graph.set(secondNodeId, secondNode);
72+
} else {
73+
secondNode = graph.get(secondNodeId);
74+
}
75+
76+
firstNode.neighbors.add(secondNode);
77+
secondNode.neighbors.add(firstNode);
78+
});
79+
return graph;
80+
}
81+
82+
class Node {
83+
constructor(id) {
84+
this.id = id;
85+
this.neighbors = new Set();
86+
}
87+
}
88+
89+
class LinkedListNode {
90+
constructor(data, next = null) {
91+
this.data = data;
92+
this.next = next;
93+
}
94+
}
95+
96+
class LinkedList {
97+
constructor(root = null) {
98+
this.root = root;
99+
this.rear = root;
100+
this.size = root ? 1 : 0;
101+
}
102+
103+
/**
104+
* Remove the head/first node of the linked list
105+
*/
106+
poll() {
107+
if (this.root) {
108+
const node = this.root;
109+
this.root = this.root.next;
110+
if (this.rear === node) {
111+
this.rear = null;
112+
}
113+
this.size--;
114+
return node;
115+
}
116+
}
117+
118+
/**
119+
* Insert a new node into the linked list
120+
* @param {LinkedListNode} node - Node to be inserted
121+
*/
122+
insert(node) {
123+
if (this.root) {
124+
this.rear.next = node;
125+
} else {
126+
this.root = node;
127+
}
128+
this.rear = node;
129+
this.size++;
130+
}
131+
}

0 commit comments

Comments
 (0)