Skip to content

Commit 7af432d

Browse files
my solution for 1334
1 parent ba76285 commit 7af432d

File tree

1 file changed

+86
-2
lines changed

1 file changed

+86
-2
lines changed

problems/1334/jeremymanning.md

+86-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,95 @@
11
# [Problem 1334: Find the City With the Smallest Number of Neighbors at a Threshold Distance](https://leetcode.com/problems/find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/description/?envType=daily-question)
22

33
## Initial thoughts (stream-of-consciousness)
4+
- There's probably a very efficient way to do this, but what comes to mind initially is that we should just start by building the graph. I'll need to think of an appropriate representation for storing the nodes/edges.
5+
- Then I think we could have a hash table (keys: nodes; values: list of other nodes reachable in less than or equal to `distanceThreshold` steps). How can we build this?
6+
- Then we can loop through the nodes and return the one with the minimum number of neighbors (and the greatest ID number if there are multiple cities with that same minimum number of neighbors)
47

58
## Refining the problem, round 2 thoughts
69

10+
### Some implementation ideas
11+
- **Graph representation:**
12+
- Option 1: hash table
13+
- Let's store nodes in a `dict` (keys: node; values: direct connections...maybe as touples so that we can also store the edge weights?)
14+
- Note: if the weight of a given connection is more than `distanceThreshold`, we can just ignore it
15+
- We should also add edges bidirectionally
16+
- Option 2: adjacency matrix:
17+
- Rows and columns are nodes, and the entries tell us how far each node is from each other node (inf if there's no edge between the nodes)
18+
- I kind of like this approach, because I suspect we could use some sort of graph traversal algorithm to propagate the edges 🤔
19+
- **Building up a table of cities within the threshold distance:**
20+
- Once we've added the edges, I think we'll need to do another loop through to see what's reachable within the threshold distance
21+
- We could do something like the following (for each node `i` in turn, in ascending order):
22+
- Set `d = distanceThreshold`
23+
- loop through everything within distance `d` of the current node. Suppose another node, `j` is in that list and is distance `x` from node `i`:
24+
- Increment node `i`'s counter
25+
- Now search for things that are within `d - x` of node `j`
26+
- Keep repeating this process until there are no more nodes within the threshold distance away
27+
- We could use either a stack or a queue to do the searching...there's probably a way to cache some of the computations so that we don't have to re-do them each time we visit a node
28+
- **Final loop:**
29+
- Initialize `minCity = [cities[0], reachable[0]]`
30+
- Then loop through each node in turn, replacing `minCity` if `reachable[i] < minCity[1] or (reachable[i] == minCity[1] and minCity[0] < cities[i])`
31+
- return `minCity[0]`
32+
- Note: since we know the cities range from `0...n-1`, we could also loop through in reverse order of the city numbers and just replace `minCity` if `reachable[i] < minCity[1]`
33+
34+
### Other notes
35+
- I think solving this efficiently will require implementing a graph traversal algorithm. Essentially we need to know the shortest path between all pairs of nodes, and then count (for each node) the number of nodes within `distanceThreshold`. Then we return the node with the most reachable nodes (and if there's a tie, pick the one with the max ID value)
36+
- On [Wikipedia's entry on shortest path graph problems](https://en.wikipedia.org/wiki/Shortest_path_problem) we can see a few options:
37+
38+
![Screenshot 2024-07-25 at 10 43 44 PM](https://github.com/user-attachments/assets/894ed832-b1d2-4118-85a7-a752700c4aea)
39+
- Of these, either the Floyd-Warshall algorithm or Johnson's algorithm will give us the shortest paths between all pairs of nodes. The entry says Johnson's algorithm is faster on sparse graphs, but we don't know whether the graph is actually sparse. Let's just pick whatever looks easier to implement.
40+
- The [Floyd-Warshall algorithm](https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm) looks straightforward:
41+
42+
![Screenshot 2024-07-25 at 10 46 21 PM](https://github.com/user-attachments/assets/6ae7c96b-ba02-4a04-956d-db28c3652cc5)
43+
44+
- [Johnson's algorithm](https://en.wikipedia.org/wiki/Johnson%27s_algorithm) isn't quite as clearly described:
45+
46+
![Screenshot 2024-07-25 at 10 47 07 PM](https://github.com/user-attachments/assets/8ffade42-0d62-4216-bb0d-b4ebd0f6289b)
47+
48+
So...let's just go with the Floyd-Warshall algorithm.
49+
- I think we're good to implmeent this now
50+
51+
752
## Attempted solution(s)
853
```python
9-
class Solution: # paste your code here!
10-
...
54+
class Solution:
55+
def findTheCity(self, n: int, edges: List[List[int]], distanceThreshold: int) -> int:
56+
# Implement the Floyd-Warshall algorithm following Wikipedia's pseudocode...
57+
# First: initialize the distances to infinity
58+
dists = [[float('inf')] * n for _ in range(n)]
59+
60+
# The distance from each node to itself is zero
61+
for i in range(n):
62+
dists[i][i] = 0
63+
64+
# Add the edges (bidirectionally)
65+
for u, v, w in edges:
66+
dists[u][v] = w
67+
dists[v][u] = w
68+
69+
# Fill in the shortest path between all pairs
70+
for k in range(n):
71+
for i in range(n):
72+
for j in range(n):
73+
if dists[i][j] > dists[i][k] + dists[k][j]:
74+
dists[i][j] = dists[i][k] + dists[k][j]
75+
76+
# now loop through each node and keep track of the city wth the minimum number of neighbors (and max ID, of those)
77+
min_neighbors = float('inf')
78+
city = -1
79+
80+
for i in range(n):
81+
# count neighbors and update the minimum if needed
82+
neighbors = sum([d <= distanceThreshold for d in dists[i]])
83+
84+
if (neighbors < min_neighbors) or ((neighbors == min_neighbors) and (i > city)):
85+
min_neighbors = neighbors
86+
city = i
87+
88+
return city
1189
```
90+
- Given test cases pass
91+
- Submitting...
92+
93+
![Screenshot 2024-07-25 at 10 59 05 PM](https://github.com/user-attachments/assets/ca8088b1-f988-4fed-80a0-08a8970e6d17)
94+
95+
Solved!

0 commit comments

Comments
 (0)