Skip to content

Instantly share code, notes, and snippets.

@AjayPoshak
Created January 22, 2022 12:42
Show Gist options
  • Save AjayPoshak/6cd473560ed429ab0d03d230f3896b37 to your computer and use it in GitHub Desktop.
Save AjayPoshak/6cd473560ed429ab0d03d230f3896b37 to your computer and use it in GitHub Desktop.
// This is an example of Dijkstra's algorithm. https://leetcode.com/problems/network-delay-time/
function createAdjList(edges, n) {
const adjList = new Map()
for(let i=0; i<n; i++) adjList.set(i, [])
for(let i=0; i<edges.length; i++) {
const [from, to, weight] = edges[i]
const neighbors = adjList.get(from)
neighbors.push({ node: to, weight })
adjList.set(from, neighbors)
}
return adjList
}
function networkDelayTime(times, n, k) {
const adjList = createAdjList(times, n)
const delayMap = new Map()
const visited = new Map()
for(let i=0; i<n; i++) delayMap.set(i, Infinity)
delayMap.set(k, 0)
findShortestPath(adjList, k, delayMap, visited, n)
let delayTime = 0
for(let i=0; i<n; i++) {
if(delayMap.get(i) === Infinity) return -1
delayTime = Math.max(delayTime, delayMap.get(i))
}
return delayTime
}
function findShortestPath(adjList, currentNode, delayMap, visited, n) {
if(visited.has(currentNode) === true) return
visited.set(currentNode, true)
const neighbors = adjList.get(currentNode)
const currentDelay = delayMap.get(currentNode)
for(let i=0; i<neighbors.length; i++) {
const {node, weight} = neighbors[i]
if(visited.has(node) === true) continue
const delayAtNeighbor = delayMap.get(node)
const newDelay = currentDelay + weight
const updatedDelay = Math.min(delayAtNeighbor, newDelay)
delayMap.set(node, updatedDelay)
}
let min = Infinity, minNode = null
for(let i=0; i<n; i++) {
if(visited.has(i) === true) continue
if(delayMap.get(i) < min) {
min = delayMap.get(i)
minNode = i
}
}
if(minNode !== null) findShortestPath(adjList, minNode, delayMap, visited, n)
}
@AjayPoshak
Copy link
Author

AjayPoshak commented Nov 21, 2022

Non recursive implementation

/**
 * @param {number[][]} times
 * @param {number} n
 * @param {number} k
 * @return {number}
 */
function addToMap(map, key, value) {
  const values = map.get(key)
  values.push(value)
  map.set(key, values)
}

var networkDelayTime = function(times, n, k) {
  const adjList = new Map()
  times.forEach((time) => {
    const [source, dest, dist] = time
    if(adjList.has(source) === false) adjList.set(source, [])
    addToMap(adjList, source, {dest, weight: dist})
  })
  
  const delays = new Array(n).fill(Infinity)
  delays[k-1] = 0
  const visited = new Map()
  let currentNode = k
  while(currentNode) {
    if(visited.has(currentNode) === true) continue
    visited.set(currentNode, true)
    let nodesToVisit = adjList.get(currentNode) || []
    while(nodesToVisit.length > 0) {
      const { dest: node, weight } = nodesToVisit.pop()
      const currentDistance = delays[node-1]
      const newDistance = weight + delays[currentNode-1]
      if(newDistance < currentDistance) {
        delays[node-1] = newDistance
      }
    }
    let minNode = null, min = Infinity
    for(let i=0; i<delays.length; i++) {
      if(visited.has(i+1) === true) continue
      if(delays[i] < min) {
        min = delays[i]
        minNode = i+1
      }
    }
    currentNode = minNode
  }
  let minDelay = -1
  for(let i=0; i<delays.length; i++) {
    minDelay = Math.max(minDelay, delays[i])
  }
  return minDelay === Infinity ? -1 : minDelay
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment