LeetCode 2852 - Sum of Remoteness of All Cells
We are given an n × n grid where each cell is either: - A positive integer, representing a valid cell with that value. - -1, representing a blocked cell. Movement is allowed only between non-blocked cells that share an edge, meaning up, down, left, or right.
Difficulty: 🟡 Medium
Topics: Array, Hash Table, Depth-First Search, Breadth-First Search, Union-Find, Matrix
Solution
LeetCode 2852 - Sum of Remoteness of All Cells
Problem Understanding
We are given an n × n grid where each cell is either:
- A positive integer, representing a valid cell with that value.
-1, representing a blocked cell.
Movement is allowed only between non-blocked cells that share an edge, meaning up, down, left, or right.
For every non-blocked cell (i, j), its remoteness R[i][j] is defined as the sum of values of all non-blocked cells that cannot be reached from (i, j) through valid movements. Blocked cells always have remoteness 0.
The task is to compute:
$$\sum R[i][j]$$
over all cells in the grid.
The key observation is that reachability partitions all non-blocked cells into connected components. Every cell inside the same connected component can reach every other cell in that component. Therefore, for a cell belonging to a component, the unreachable cells are exactly all cells that belong to other components.
The constraints are important:
n ≤ 300- The grid can contain up to
300 × 300 = 90,000cells. - Cell values can be as large as
10^6.
A solution that performs a graph traversal from every non-blocked cell would be far too slow. We need an algorithm that processes each cell only a constant number of times.
Several edge cases deserve attention:
- The entire grid may consist of blocked cells.
- The grid may contain exactly one connected component.
- Every non-blocked cell may be isolated.
- Cell values can be large, requiring 64-bit arithmetic.
- A single-cell grid should correctly return
0.
Approaches
Brute Force
A straightforward solution would compute R[i][j] independently for every non-blocked cell.
For each cell:
- Run BFS or DFS to find all reachable cells.
- Sum the values of all unreachable cells.
- Add that remoteness value to the final answer.
This is correct because reachability is computed exactly for each cell.
However, if there are k non-blocked cells, we may perform a traversal of up to O(k) cells for each starting cell, resulting in:
$$O(k^2)$$
time complexity.
Since k can be as large as 90,000, this approach is completely infeasible.
Optimal Approach
The important observation is that all cells within the same connected component have exactly the same set of reachable cells.
Suppose:
totalSum= sum of values of all non-blocked cells.- A connected component has value sum
componentSum.
Then every cell in that component has remoteness:
$$totalSum - componentSum$$
because every cell outside the component is unreachable.
If the component contains size cells, its total contribution to the answer is:
$$size \times (totalSum - componentSum)$$
Therefore:
- Compute the total value of all non-blocked cells.
- Find every connected component using DFS, BFS, or Union-Find.
- For each component, determine:
- Number of cells in the component.
- Sum of values inside the component.
- Add the component's contribution.
This avoids repeated traversals and processes each cell only once.
Approach Comparison
| Approach | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Brute Force | O(k²) | O(k) | Run BFS/DFS from every non-blocked cell |
| Optimal | O(n²) | O(n²) | Find connected components once |
where k is the number of non-blocked cells.
Algorithm Walkthrough
Step 1
Compute the sum of values of all non-blocked cells.
Store this value in totalSum.
This allows us to later compute the unreachable value sum for any component using subtraction rather than explicitly enumerating unreachable cells.
Step 2
Create a visited matrix of size n × n.
This ensures every non-blocked cell is processed exactly once.
Step 3
Iterate through every cell in the grid.
Whenever an unvisited non-blocked cell is found, it must be the start of a new connected component.
Step 4
Perform DFS or BFS from that cell.
During the traversal:
- Count how many cells belong to the component.
- Accumulate the sum of their values.
Let these be:
componentSizecomponentSum
Step 5
Once the component is fully explored, compute:
$$componentContribution = componentSize \times (totalSum - componentSum)$$
Every cell in the component has remoteness equal to totalSum - componentSum.
Since there are componentSize such cells, multiplying gives the total contribution of the component.
Step 6
Add this contribution to the answer.
Step 7
Continue until all cells have been processed.
Return the accumulated answer.
Why it works
Every non-blocked cell belongs to exactly one connected component. All cells in the same component can reach exactly the same set of cells, namely every cell in that component. Therefore, the unreachable cells for any member of the component are precisely all cells outside the component.
If the sum of all valid cell values is totalSum and the component value sum is componentSum, then the unreachable value sum is totalSum - componentSum. Since every cell in the component has this same remoteness value, multiplying by the component size gives the total contribution of that component. Summing contributions over all components counts every R[i][j] exactly once.
Python Solution
from typing import List
from collections import deque
class Solution:
def sumRemoteness(self, grid: List[List[int]]) -> int:
n = len(grid)
total_sum = 0
for row in grid:
for value in row:
if value != -1:
total_sum += value
visited = [[False] * n for _ in range(n)]
answer = 0
directions = ((1, 0), (-1, 0), (0, 1), (0, -1))
for r in range(n):
for c in range(n):
if grid[r][c] == -1 or visited[r][c]:
continue
queue = deque([(r, c)])
visited[r][c] = True
component_size = 0
component_sum = 0
while queue:
x, y = queue.popleft()
component_size += 1
component_sum += grid[x][y]
for dx, dy in directions:
nx = x + dx
ny = y + dy
if (
0 <= nx < n
and 0 <= ny < n
and grid[nx][ny] != -1
and not visited[nx][ny]
):
visited[nx][ny] = True
queue.append((nx, ny))
answer += component_size * (total_sum - component_sum)
return answer
The implementation begins by computing total_sum, the sum of all non-blocked cell values.
A visited matrix prevents revisiting cells during component exploration.
The outer loops scan every grid position. Whenever an unvisited non-blocked cell is found, a BFS starts from that position. During the BFS, the algorithm tracks both the number of cells in the component and the sum of their values.
After the component has been completely explored, the contribution formula
$$componentSize \times (totalSum - componentSum)$$
is applied and added to the answer.
Because every cell enters the queue at most once, the overall runtime remains linear in the number of grid cells.
Go Solution
func sumRemoteness(grid [][]int) int64 {
n := len(grid)
var totalSum int64
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
if grid[i][j] != -1 {
totalSum += int64(grid[i][j])
}
}
}
visited := make([][]bool, n)
for i := range visited {
visited[i] = make([]bool, n)
}
dirs := [][2]int{
{1, 0},
{-1, 0},
{0, 1},
{0, -1},
}
var answer int64
for r := 0; r < n; r++ {
for c := 0; c < n; c++ {
if grid[r][c] == -1 || visited[r][c] {
continue
}
queue := [][2]int{{r, c}}
visited[r][c] = true
var componentSize int64
var componentSum int64
for head := 0; head < len(queue); head++ {
x := queue[head][0]
y := queue[head][1]
componentSize++
componentSum += int64(grid[x][y])
for _, d := range dirs {
nx := x + d[0]
ny := y + d[1]
if nx < 0 || nx >= n || ny < 0 || ny >= n {
continue
}
if grid[nx][ny] == -1 || visited[nx][ny] {
continue
}
visited[nx][ny] = true
queue = append(queue, [2]int{nx, ny})
}
}
answer += componentSize * (totalSum - componentSum)
}
}
return answer
}
Go-Specific Notes
The maximum possible answer exceeds 32-bit integer limits. Therefore all sums and the final answer use int64.
Instead of Python's deque, the Go implementation uses a slice with a moving head index, which provides an efficient queue implementation without repeatedly removing elements from the front.
Worked Examples
Example 1
grid =
[
[-1,1,-1],
[5,-1,4],
[-1,3,-1]
]
Step 1: Compute Total Sum
| Cell Value |
|---|
| 1 |
| 5 |
| 4 |
| 3 |
$$totalSum = 1 + 5 + 4 + 3 = 13$$
Step 2: Find Components
Each non-blocked cell is isolated.
| Component | Cells | Component Sum | Size |
|---|---|---|---|
| C1 | {(0,1)} | 1 | 1 |
| C2 | {(1,0)} | 5 | 1 |
| C3 | {(1,2)} | 4 | 1 |
| C4 | {(2,1)} | 3 | 1 |
Step 3: Contributions
| Component | Contribution |
|---|---|
| C1 | 1 × (13 - 1) = 12 |
| C2 | 1 × (13 - 5) = 8 |
| C3 | 1 × (13 - 4) = 9 |
| C4 | 1 × (13 - 3) = 10 |
$$12 + 8 + 9 + 10 = 39$$
Answer = 39
Example 2
grid =
[
[-1,3,4],
[-1,-1,-1],
[3,-1,-1]
]
Total Sum
$$3 + 4 + 3 = 10$$
Components
| Component | Cells | Sum | Size |
|---|---|---|---|
| C1 | {(0,1),(0,2)} | 7 | 2 |
| C2 | {(2,0)} | 3 | 1 |
Contributions
| Component | Contribution |
|---|---|
| C1 | 2 × (10 - 7) = 6 |
| C2 | 1 × (10 - 3) = 7 |
$$6 + 7 = 13$$
Answer = 13
Example 3
grid = [[1]]
Total Sum
$$1$$
Components
| Component | Sum | Size |
|---|---|---|
| C1 | 1 | 1 |
Contribution
$$1 \times (1 - 1) = 0$$
Answer = 0
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(n²) | Every cell is visited at most once |
| Space | O(n²) | Visited matrix plus BFS queue |
The BFS explores each non-blocked cell exactly once. Since there are at most n² cells, the total work performed across all component traversals is O(n²). The visited matrix also requires O(n²) space, and in the worst case the queue may contain O(n²) cells.
Test Cases
sol = Solution()
assert sol.sumRemoteness([[1]]) == 0 # single valid cell
assert sol.sumRemoteness([
[-1, 1, -1],
[5, -1, 4],
[-1, 3, -1]
]) == 39 # example 1
assert sol.sumRemoteness([
[-1, 3, 4],
[-1, -1, -1],
[3, -1, -1]
]) == 13 # example 2
assert sol.sumRemoteness([
[1, 2],
[3, 4]
]) == 0 # one connected component
assert sol.sumRemoteness([
[1, -1],
[-1, 2]
]) == 3 # two isolated cells
assert sol.sumRemoteness([
[-1, -1],
[-1, -1]
]) == 0 # all blocked
assert sol.sumRemoteness([
[10]
]) == 0 # single cell with large value
assert sol.sumRemoteness([
[1, 1, 1],
[1, -1, 1],
[1, 1, 1]
]) == 0 # component connected around obstacle
assert sol.sumRemoteness([
[1, -1, 2],
[-1, -1, -1],
[3, -1, 4]
]) == 20 # four isolated components
assert sol.sumRemoteness([
[1000000, -1],
[-1, 1000000]
]) == 2000000 # verifies large values
Test Summary
| Test | Why |
|---|---|
[[1]] |
Minimum grid size |
| Example 1 | Official example with isolated cells |
| Example 2 | Official example with one multi-cell component |
| Fully connected 2×2 grid | Remoteness should be zero everywhere |
| Two isolated cells | Small disconnected case |
| All blocked cells | No valid cells exist |
| Single large value | Boundary value check |
| Connected around obstacle | Verifies proper graph connectivity |
| Four isolated components | Many disconnected regions |
| Large values | Confirms 64-bit arithmetic correctness |
Edge Cases
All Cells Are Blocked
A grid may contain only -1 values. In this situation there are no connected components and every cell already has remoteness 0.
A buggy implementation might attempt to start traversals from blocked cells or incorrectly compute component contributions. The presented solution skips all blocked cells and therefore returns 0.
One Giant Connected Component
If every non-blocked cell belongs to a single connected component, then every cell can reach every other non-blocked cell.
In that case:
$$totalSum = componentSum$$
and the contribution becomes zero. The algorithm naturally handles this because it computes totalSum - componentSum.
Many Isolated Cells
A checkerboard-like arrangement can create thousands of single-cell components.
A naive solution would repeatedly traverse almost the entire grid for every cell. The optimal solution remains efficient because each isolated cell is discovered exactly once and contributes:
$$1 \times (totalSum - cellValue)$$
to the answer.
Large Cell Values
Each cell value may be as large as 10^6, and there may be up to 90,000 non-blocked cells. The total sum can therefore reach approximately:
$$9 \times 10^{10}$$
which exceeds 32-bit integer limits.
The Python solution uses arbitrary-precision integers automatically, and the Go solution explicitly uses int64 for all accumulated sums and the final answer.