2Brute2Best
🔥0

Find the City With the Smallest Number of Neighbors at a Threshold Distance

Medium·LeetCode #1334Basic Anchor
LeetCode
30-Second Mental ModelShortest Paths (weighted): All pairs (Floyd-Warshall)
Complexity:O(N² · E)→O(N³)
Key Insight

Start with d[i][j] = the road cost (0 on the diagonal, ∞ if there is no road). Then for each city k in turn, try k as a middle stop for every pair: d[i][j] = min(d[i][j], d[i][k] + d[k][j]). After all the k rounds, d holds every shortest distance. Then count, for each city, the others within the threshold, and keep the fewest. On a tie keep the greater city.

Core Validity Invariant

After the round for k, d[i][j] is the shortest distance from i to j whose middle cities all lie in 0..k, for every pair (i, j).

01

Problem

There are n cities, numbered 0 to n − 1, joined by two-way roads. Each road is [a, b, w]: it links cities a and b, and travelling it costs w.

The distance between two cities is the cost of the cheapest route between them. For each city, count the other cities whose distance is at most distanceThreshold. Return the city with the fewest such cities. If several cities tie, return the one with the greatest number.

Input

n, edges (a list of [a, b, w]) and distanceThreshold.

Output

The number of the city with the fewest neighbours within the threshold. A tie goes to the greater city number.

Example 1
Input: n = 4, edges = [[0,1,3],[1,2,1],[1,3,4],[2,3,1]], distanceThreshold = 4
Output: 3

City 0 has 2 neighbours within 4 (cities 1 and 2). City 1 has 3, city 2 has 3, and city 3 has 2 (cities 1 and 2). Cities 0 and 3 tie at 2, so we return the greater number, 3.

Example 2
Input: n = 5, edges = [[0,1,2],[0,4,8],[1,2,3],[1,4,2],[2,3,1],[3,4,1]], distanceThreshold = 2
Output: 0

City 0 has only one neighbour within 2 (city 1, at distance 2). Every other city has at least two.

Constraints
  • • 2 ≤ n ≤ 100
  • • 1 ≤ edges.length ≤ n · (n − 1) / 2
  • • edges[i].length == 3
  • • 0 ≤ from < to < n
  • • 1 ≤ weight, distanceThreshold ≤ 10^4
  • • All pairs (from, to) are distinct.
02

First, think yourself

Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.

  1. 1.

    The count for each city depends on its distance to every other city. Do I need one search per city, or can I get every distance in one go?

  2. 2.

    If I run one shortest-path search from each city, how many searches do I run, and how many roads does each one scan?

  3. 3.

    When a route passes through city k, which two shorter routes does it join? Do those two routes need to be finished first?

  4. 4.

    Two cities can tie on the count. Which one does the statement pick, and how do I make the loop pick it without sorting?

  5. 5.

    Which of the three loops has to be the outermost one, and what does that loop mean?

03

Brute force approach

05

Optimized approach

06

Why does this algorithm work?

07

Dry run

08

All approaches compared

ApproachIdeaTimeSpace
Brute ForceRun Bellman-Ford from each city, count the cities within the threshold, keep the fewestO(N² · E)O(N)
OptimalAll-pairs distances in O(N³) with the middle city as the outer loop, then count per cityO(N³)O(N²)
09

Why does this belong to this pattern?

Clues in the problem statement
  • “for each city, count the cities within the threshold”Distances between every pair are needed, not from one start. That points to all-pairs shortest paths.
  • “n ≤ 100”N³ is about 10^6 steps, which is fast, so Floyd-Warshall is affordable.
  • “fewest, and the greatest number on a tie”Compare with <= while scanning the cities in order, so the later city wins a tie.
weighted roads+all pairs of cities+count within threshold per city+tie goes to the larger index→Shortest Paths (weighted): All pairs (Floyd-Warshall)

The distance is the same sum of road costs as in Dijkstra. What is new is that every pair is needed, so one run from one source is not enough. Floyd-Warshall gives all the distances in O(N³), and then one counting pass per city answers the question. The middle-city loop must be outermost: after round k, d[i][j] only covers middle cities 0..k, so putting the loop inside would give wrong distances.

10

Don't make this mistake

Breaking ties by the smaller index
✗ if (count < fewest) { fewest = count; city = i; }
✓ if (count <= fewest) { fewest = count; city = i; }

This is the pattern-confusion trap: the usual 'keep the first best' habit. On example 1 the counts are [2, 3, 3, 2]. With < the first city with 2 wins, which is city 0. The statement asks for the greater number, so the answer is 3.

Putting the k loop inside (wrong distances)
✗ for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) for (int k = 0; k < n; k++) ...
✓ for (int k = 0; k < n; k++) for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) ...

Take the roads 0–1 (1), 1–3 (5) and 2–3 (3). The true distance from 0 to 2 is 9 (0 → 1 → 3 → 2). With i, j, k order, when i = 0 and j = 2 is checked, d[0][3] is still ∞, because it is only set later when j = 3 runs. So d[0][2] stays ∞. Example 1 still comes out right, which is why this bug is easy to miss.

Using < instead of <= for the threshold
✗ if (d[i][j] < distanceThreshold) count++;
✓ if (d[i][j] <= distanceThreshold) count++;

The statement says 'at most'. On example 1, d[0][2] = 4 is exactly the threshold. With <, city 0 has only 1 neighbour, so the answer becomes 0 instead of 3.

INF = INT_MAX, so the sum overflows
✗ const int INF = INT_MAX; // then d[i][k] + d[k][j] can overflow
✓ const int INF = INT_MAX / 2; // two INFs add up without overflowing

INT_MAX + INT_MAX does not fit in an int. In C++ that is undefined behaviour, and in practice the sum wraps to a negative number, which looks shorter than any real route. Halving INF keeps every sum safe.

11

Want to implement this?

Write it yourself on LeetCode, then come back and compare your code with the solutions above.

Open coding workspace
How did it go?
Beyond The LeetCode Problem

How this concept connects to System Design & C++ Systems

Bridge DSA with production engineering

Top engineering interviews test whether you understand how algorithms like Shortest Paths (Weighted) translate into production architectures and low-level memory mechanics.