July 26th, 2024
All pair shortest path
Edit me
#. Problem
1. My approach
All pair shortest path - O(n^3)
Not very optimal on readability, but here it is:
/**
* @param {number} n
* @param {number[][]} edges
* @param {number} distanceThreshold
* @return {number}
*/
var findTheCity = function(n, edges, distanceThreshold) {
const dp = Array.from({length: n}, el => Array.from({length:n}, el => 0));
for(const [u, v, weight] of edges){
dp[u][v] = weight;
dp[v][u] = weight;
}
for(let u = 0; u < n; u++){
for(let v = 0; v < n; v++){
if(u === v) continue;
for(let w = 0; w < n; w++){
if(u === w || v === w) continue;
const uToW = dp[u][w];
const wToV = dp[w][v];
const uToV = dp[u][v];
if(!uToW || !wToV) continue;
const UtoWtoV = uToW + wToV;
if(!uToV || UtoWtoV < uToV){
dp[u][v] = uToW + wToV;
dp[v][u] = uToW + wToV;
}
}
}
}
const possibleCities = [];
let minNum = 999;
for(let u = 0; u < n; u++){
let count = 0;
for(let v = 0; v < n; v++){
if(!dp[u][v]) continue;
if(dp[u][v] <= distanceThreshold) count++;
}
possibleCities.push(count);
minNum = Math.min(minNum, count);
}
return possibleCities.lastIndexOf(minNum);
};
This encountered a problem on specific conditions.
w
should be the most outer loop, because by putting w
inside the inner loop, it make array dp
not optimal.
On the time when dp[u][w] + d[w][v] < dp[u][v]
, it has to be ensured that dp[u][w]
and dp[w][v]
is containing the shortest path already.
So by putting w
outside the inner loop, it’s solved.
2. Solution(refactoring)
/**
* @param {number} n
* @param {number[][]} edges
* @param {number} distanceThreshold
* @return {number}
*/
var findTheCity = function(n, edges, distanceThreshold) {
// Initialize all distances to Infinity - not reachable from any city
const dp = Array.from({length: n}, () => Array.from({length: n}, () => Infinity));
// Set the direct distances from the edges and 0 for the diagonal
for (let i = 0; i < n; i++) {
dp[i][i] = 0;
}
for (const [u, v, weight] of edges) {
dp[u][v] = weight;
dp[v][u] = weight;
}
// Floyd-Warshall algorithm to find all-pairs shortest paths
for (let k = 0; k < n; k++) {
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (dp[i][k] + dp[k][j] < dp[i][j]) {
dp[i][j] = dp[i][k] + dp[k][j];
}
}
}
}
// Find the city with the smallest number of cities within the distance threshold
let minNum = Infinity;
let resultCity = -1;
for (let i = 0; i < n; i++) {
let count = 0;
for (let j = 0; j < n; j++) {
if (i !== j && dp[i][j] <= distanceThreshold) {
count++;
}
}
if (count <= minNum) {
minNum = count;
resultCity = i;
}
}
return resultCity;
};
Time - O(n^3) | Space - O(n^2) |
---|---|
84 ms | 55 MB |
3. Epilogue
What I’ve learned from this exercise:
small details … focus.