LeetCode 2850. Minimum Moves to Spread Stones Over Grid Solution in Java, C++, Python & More | Explanation + Code

CoderIndeed
0
2850. Minimum Moves to Spread Stones Over Grid

Description

You are given a 0-indexed 2D integer matrix grid of size 3 * 3, representing the number of stones in each cell. The grid contains exactly 9 stones, and there can be multiple stones in a single cell.

In one move, you can move a single stone from its current cell to any other cell if the two cells share a side.

Return the minimum number of moves required to place one stone in each cell.

 

Example 1:

Input: grid = [[1,1,0],[1,1,1],[1,2,1]]
Output: 3
Explanation: One possible sequence of moves to place one stone in each cell is: 
1- Move one stone from cell (2,1) to cell (2,2).
2- Move one stone from cell (2,2) to cell (1,2).
3- Move one stone from cell (1,2) to cell (0,2).
In total, it takes 3 moves to place one stone in each cell of the grid.
It can be shown that 3 is the minimum number of moves required to place one stone in each cell.

Example 2:

Input: grid = [[1,3,0],[1,0,0],[1,0,3]]
Output: 4
Explanation: One possible sequence of moves to place one stone in each cell is:
1- Move one stone from cell (0,1) to cell (0,2).
2- Move one stone from cell (0,1) to cell (1,1).
3- Move one stone from cell (2,2) to cell (1,2).
4- Move one stone from cell (2,2) to cell (2,1).
In total, it takes 4 moves to place one stone in each cell of the grid.
It can be shown that 4 is the minimum number of moves required to place one stone in each cell.

 

Constraints:

  • grid.length == grid[i].length == 3
  • 0 <= grid[i][j] <= 9
  • Sum of grid is equal to 9.

Solutions

Solution 1: Naive BFS

The problem is essentially finding the shortest path from the initial state to the target state in a state graph, so we can use BFS to solve it. The initial state is grid, and the target state is [[1, 1, 1], [1, 1, 1], [1, 1, 1]]. In each operation, we can move a stone greater than 1 from a cell to an adjacent cell that does not exceed 1. If the target state is found, we can return the current layer number, which is the minimum number of moves.

PythonJavaC++GoTypeScript
class Solution: def minimumMoves(self, grid: List[List[int]]) -> int: q = deque([tuple(tuple(row) for row in grid)]) vis = set(q) ans = 0 dirs = (-1, 0, 1, 0, -1) while 1: for _ in range(len(q)): cur = q.popleft() if all(x for row in cur for x in row): return ans for i in range(3): for j in range(3): if cur[i][j] > 1: for a, b in pairwise(dirs): x, y = i + a, j + b if 0 <= x < 3 and 0 <= y < 3 and cur[x][y] < 2: nxt = [list(row) for row in cur] nxt[i][j] -= 1 nxt[x][y] += 1 nxt = tuple(tuple(row) for row in nxt) if nxt not in vis: vis.add(nxt) q.append(nxt) ans += 1(code-box)

Solution 2: State Compression Dynamic Programming

We can put all the coordinates (i, j) of cells with a value of 0 into an array left. If the value v of a cell is greater than 1, we put v-1 coordinates (i, j) into an array right. The problem then becomes that each coordinate (i, j) in right needs to be moved to a coordinate (x, y) in left, and we need to find the minimum number of moves.

Let's denote the length of left as n. We can use an n-bit binary number to represent whether each coordinate in left is filled by a coordinate in right, where 1 represents being filled, and 0 represents not being filled. Initially, f[i] = ∞, and the rest f[0]=0.

Consider f[i], let the number of 1s in the binary representation of i be k. We enumerate j in the range [0..n), if the jth bit of i is 1, then f[i] can be transferred from f[i \oplus (1 << j)], and the cost of the transfer is cal(left[k-1], right[j]), where cal represents the Manhattan distance between two coordinates. The final answer is f[(1 << n) - 1].

The time complexity is O(n × 2n), and the space complexity is O(2n). Here, n is the length of left, and in this problem, n \le 9.

PythonJavaC++GoTypeScript
class Solution: def minimumMoves(self, grid: List[List[int]]) -> int: def cal(a: tuple, b: tuple) -> int: return abs(a[0] - b[0]) + abs(a[1] - b[1]) left, right = [], [] for i in range(3): for j in range(3): if grid[i][j] == 0: left.append((i, j)) else: for _ in range(grid[i][j] - 1): right.append((i, j)) n = len(left) f = [inf] * (1 << n) f[0] = 0 for i in range(1, 1 << n): k = i.bit_count() for j in range(n): if i >> j & 1: f[i] = min(f[i], f[i ^ (1 << j)] + cal(left[k - 1], right[j])) return f[-1](code-box)

Post a Comment

0Comments

Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Check Now
Accept !