LeetCode 3015 - Count the Number of Houses at a Certain Distance I
Here is a complete technical solution guide for LeetCode 3015 - Count the Number of Houses at a Certain Distance I, formatted according to your specifications. The problem describes a simple linear city with n houses numbered from 1 to n.
Difficulty: 🟡 Medium
Topics: Breadth-First Search, Graph Theory, Prefix Sum
Solution
Here is a complete technical solution guide for LeetCode 3015 - Count the Number of Houses at a Certain Distance I, formatted according to your specifications.
Problem Understanding
The problem describes a simple linear city with n houses numbered from 1 to n. Each consecutive house i and i + 1 are connected by streets, forming a linear path. Additionally, a special street directly connects two houses x and y. The task is to count, for each distance k from 1 to n, the number of ordered pairs of houses (house1, house2) such that the shortest path (minimum number of streets) between them is exactly k.
Inputs:
n(number of houses, up to 100)x,y(special street endpoints, may be equal)
Output:
- A 1-indexed array
resultof lengthnwhereresult[k]is the number of pairs of houses with minimum street distancek.
Important points:
- Distance is symmetric but ordered pairs are counted separately, i.e.,
(i, j)and(j, i)are distinct. xandycan be the same house; in that case, the additional street has no effect.- Constraints are small (
n <= 100), which allows O(n²) solutions.
Edge cases to note:
- When
x == y, the special street does not change distances. - Minimum or maximum
nvalues. - Distances at the extremes (1 and
n-1) may have fewer or no pairs.
Approaches
Brute Force
The brute-force approach would construct an adjacency list for all n houses, perform a BFS starting from each house to compute distances to every other house, and then tally counts for each distance. This approach is correct but requires O(n³) time because for each house BFS explores up to n neighbors, repeated n times. Although feasible for n = 100, it is inefficient.
Optimal Approach
The key insight is that the city is almost linear, with only one shortcut street (x, y). For any pair of houses (i, j), the shortest distance is:
distance(i, j) = min(|i - j|, |i - x| + 1 + |y - j|, |i - y| + 1 + |x - j|)
Explanation:
|i - j|is the direct linear distance.|i - x| + 1 + |y - j|is the distance using the special street fromxtoy.|i - y| + 1 + |x - j|is the distance using the special street in the opposite direction.
We can compute this directly for all i < j and double the count for ordered pairs (i, j) and (j, i). This results in a clear O(n²) solution, which is optimal given the constraints.
Comparison table:
| Approach | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Brute Force BFS | O(n³) | O(n²) | Build adjacency list and BFS from every node |
| Optimal Direct Formula | O(n²) | O(n) | Compute minimum distance using linear path + special street formula |
Algorithm Walkthrough
- Initialize an array
resultof lengthnwith zeros.result[k]will store the count for distancek. - Iterate over all pairs of houses
(i, j)with1 <= i < j <= n. - For each pair, compute the distance using the formula:
dist = min(|i - j|, |i - x| + 1 + |y - j|, |i - y| + 1 + |x - j|)
Here, |i - j| is the linear distance, and the other two terms account for the shortcut street.
4. Increment result[dist] by 2 because we count both (i, j) and (j, i) as valid pairs.
5. After iterating all pairs, return result.
Why it works:
- The formula captures all possible shortest paths: linear distance and via the shortcut.
- By only iterating
i < jand doubling, we avoid double-counting while correctly considering ordered pairs. - The approach is efficient because
n ≤ 100ensures thatn²operations are manageable.
Python Solution
from typing import List
class Solution:
def countOfPairs(self, n: int, x: int, y: int) -> List[int]:
result = [0] * n
for i in range(1, n + 1):
for j in range(i + 1, n + 1):
dist = min(abs(i - j), abs(i - x) + 1 + abs(y - j), abs(i - y) + 1 + abs(x - j))
result[dist] += 2 # count both (i, j) and (j, i)
return result
Explanation:
resultis initialized with zeros to hold counts for each distance.- We loop over all
i < jto avoid redundant calculations. - The distance formula checks linear and shortcut paths.
- We increment by 2 to account for ordered pairs.
Go Solution
func countOfPairs(n int, x int, y int) []int {
result := make([]int, n)
for i := 1; i <= n; i++ {
for j := i + 1; j <= n; j++ {
linear := abs(i - j)
viaXY := abs(i - x) + 1 + abs(y - j)
viaYX := abs(i - y) + 1 + abs(x - j)
dist := min(linear, min(viaXY, viaYX))
result[dist] += 2
}
}
return result
}
func abs(a int) int {
if a < 0 {
return -a
}
return a
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
Go-specific notes:
- Slices are used for dynamic arrays.
- Helper functions
absandminare defined for readability. - The logic mirrors Python closely; iteration uses
1-based indices to match house numbering.
Worked Examples
Example 1: n = 3, x = 1, y = 3
Pairs (i, j) with distances:
| i | j | Linear | via XY | via YX | Min | Count Added |
|---|---|---|---|---|---|---|
| 1 | 2 | 1 | 3 | 3 | 1 | 2 |
| 1 | 3 | 2 | 1 | 1 | 1 | 2 |
| 2 | 3 | 1 | 3 | 3 | 1 | 2 |
result = [6, 0, 0]
Example 2: n = 5, x = 2, y = 4
Pairs and distances:
| i | j | Min Distance | Count Added |
|---|---|---|---|
| 1 | 2 | 1 | 2 |
| 1 | 3 | 2 | 2 |
| 1 | 4 | 2 | 2 |
| 1 | 5 | 3 | 2 |
| 2 | 3 | 1 | 2 |
| 2 | 4 | 1 | 2 |
| 2 | 5 | 2 | 2 |
| 3 | 4 | 1 | 2 |
| 3 | 5 | 2 | 2 |
| 4 | 5 | 1 | 2 |
result = [10, 8, 2, 0, 0]
Example 3: n = 4, x = 1, y = 1
result = [6, 4, 2, 0]
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(n²) | We iterate over all pairs (i, j) with i < j, which is ~n²/2. Each distance computation is O(1). |
| Space | O(n) | We store counts in an array of length n. No additional data structures needed. |
Since n ≤ 100, O(n²) operations (~10,000) are easily manageable.
Test Cases
# Provided examples
assert Solution().countOfPairs(3, 1, 3) == [6, 0, 0] # linear with shortcut spanning ends
assert Solution().countOfPairs(5, 2, 4)