Problem Statement in English
You’re given a 2D grid of size m x n where each cell contains a non-negative integer representing the number of stones in that cell. You can perform the following operation any number of times:
- Choose a cell with at least one stone and move one stone from that cell to an adjacent cell (up, down, left, or right).
Your task is to determine the minimum number of moves required to spread all the stones in the grid such that no cell contains more than one stone. If it’s impossible to achieve this, return -1.
Approach
You can’t be greedy here. You have to try all possible combinations of moving the stones to the empty cells. This is because choosing a stone as donor may result in teh starvation of another that now has to get its stone from a farther cell.
You can use a recursive approach to try all combinations and keep track of the minimum moves required.
And we’re done!
Solution in Python
class Solution:
def minimumMoves(self, grid: List[List[int]]) -> int:
empty = []
hm = defaultdict(int)
M = len(grid)
N = len(grid[0])
for i in range(M):
for j in range(N):
if grid[i][j] == 0:
empty.append((i, j))
elif grid[i][j] > 1:
hm[(i, j)] = grid[i][j]
def cost(x1, y1, x2, y2):
return abs(x1 - x2) + abs(y1 - y2)
E = len(empty)
res = inf
def dfs(i, moves):
if i >= E:
nonlocal res
res = min(res, moves)
return
for k, v in hm.items():
if v == 1: continue
hm[k] -= 1
dfs(i + 1, moves + cost(k[0], k[1], empty[i][0], empty[i][1]))
hm[k] += 1
dfs(0, 0)
return res
Complexity
Time: $O(8^8)$
This is because we have at most 8 empty cells and for each cell we can choose from at most 8 donors.Space: $O(8)$
Since we have at most 8 empty cells and we are using a recursive approach, the maximum depth of the recursion will be 8.
Mistakes I Made
I went with the greedy approach :(
And we are done.