






















This question is about implementing a basic elimination algorithm for Candy Crush.
Given an m x n integer array board representing the grid of candy where board[i][j] represents the type of candy. A value of board[i][j] == 0 represents that the cell is empty.
The given board represents the state of the game following the player's move. Now, you need to restore the board to a stable state by crushing candies according to the following rules:
You need to perform the above rules until the board becomes stable, then return the stable board.
Example 1:

Input: board = [[110,5,112,113,114],[210,211,5,213,214],[310,311,3,313,314],[410,411,412,5,414],[5,1,512,3,3],[610,4,1,613,614],[710,1,2,713,714],[810,1,2,1,1],[1,1,2,2,2],[4,1,4,4,1014]] Output: [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[110,0,0,0,114],[210,0,0,0,214],[310,0,0,113,314],[410,0,0,213,414],[610,211,112,313,614],[710,311,412,613,714],[810,411,512,713,1014]]
Example 2:
Input: board = [[1,3,5,5,2],[3,4,3,3,1],[3,2,4,5,2],[2,4,4,5,5],[1,4,4,1,1]] Output: [[1,3,0,0,0],[3,4,0,5,2],[3,2,0,3,1],[2,4,0,5,2],[1,4,3,1,1]]Solution
The game process may be somewhat complex. Let's start by understanding the game steps and finding the corresponding actions for each step. We can divide this game into several (potentially repeating) steps:
Find stands for finding all crushable candies, crush represents the elimination of adjacent candies, while drop involves rearranging the candies and making the ones above fall down. We mention that these steps are potentially repeated because after a drop, the rearranged candies may form new groups of candies to be crushed, requiring us to repeat the steps until we can no longer find a group of crushable candies.

Starting from the first step: find and mark cells in the current board to be crushed. One simple approach is to check if three candies in the same row or column centered around a particular cell (r, c), are the same. That is, either board[r][c] = board[r - 1][c] = board[r + 1][c], or board[r][c] = board[r][c - 1] = board[r][c + 1]. If certain candies meet these conditions and qualify as crushable candies, we can store their positions.

After iterating through all the cells, if no new candies to be crushed are found, it indicates that the game is over. Otherwise, we continue with crushing candies. We modify the values of the stored candy positions to 0, indicating that they have been eliminated. At this point, we have completed the second step of the game.

In the third step, we need to make the candies above fall down until they hit the bottom or another candy.
During this process, the candies can only fall downwards, meaning that each column of the board is independent. It would be helpful to discuss them separately for easier computation.

For each column, we traverse from bottom to top. Throughout this process, we keep track of the position of the lowest 0 value. If the current cell is not 0, it will eventually fall to this lowest 0 position. Therefore, we swap its position with the position of the lowest 0, and raise the position of the lowest 0 by 1.

In summary, through the aforementioned three steps, we obtain a new board.

Next, we need to continue checking if there are any crushable candies in the new grid. If we discover new crushable candies, we repeat these steps again.

Finally, when no group of crushable candies can be found, it indicates that the game is over.

Define find() to find all crushable candies:
crushed_set.(r, c):
board[r][c] = 0, continue.board[r][c] = board[r + 1][c] = board[r - 1][c], add (r, c), (r + 1, c) and (r - 1, c) to the set. If board[r][c] = board[r][c + 1] = board[r][c - 1], add (r, c), (r, c + 1) and (r, c - 1) to the set.crushed_set.Define crush(crushed_set) to mark all crushable candies:
(r, c) in crushed_set and set board[r][c] = 0.Define drop() to rearrange the candies' new positions based on the rules:
c.lowest_zero as -1 since there is no lowest zero yet.(r, c) from bottom to top, for each candy board[r][c]. If board[r][c] is zero, update lowest_zero as lowest_zero = max(lowest_zero, r). If board[r][c] is non-zero and lowest_zero is not -1, then we swap board[r][c] with board[lowest_zero][c] and decrement lowest_zero by 1.While find() returns an non-empty set crushed_set:
crush(crushed_set).drop().Return board when the while loop is complete.
1 class Solution: 2 def candyCrush(self, board: List[List[int]]) -> List[List[int]]: 3 m, n = len(board), len(board[0]) 4 5 def find(): 6 crushed_set = set() 7 8 # Check vertically adjacent candies 9 for r in range(1, m - 1): 10 for c in range(n): 11 if board[r][c] == 0: 12 continue 13 if board[r][c] == board[r - 1][c] == board[r + 1][c]: 14 crushed_set.add((r, c)) 15 crushed_set.add((r - 1, c)) 16 crushed_set.add((r + 1, c)) 17 18 # Check horizontally adjacent candies 19 for r in range(m): 20 for c in range(1, n - 1): 21 if board[r][c] == 0: 22 continue 23 if board[r][c] == board[r][c - 1] == board[r][c + 1]: 24 crushed_set.add((r, c)) 25 crushed_set.add((r, c - 1)) 26 crushed_set.add((r, c + 1)) 27 return crushed_set 28 29 # Set the value of each candies to be crushed as 0 30 def crush(crushed_set): 31 for (r, c) in crushed_set: 32 board[r][c] = 0 33 34 def drop(): 35 for c in range(n): 36 lowest_zero = -1 37 for r in range(m - 1, -1, -1): 38 if board[r][c] == 0: 39 lowest_zero = max(lowest_zero, r) 40 else: 41 if lowest_zero >= 0: 42 board[r][c], board[lowest_zero][c] = board[lowest_zero][c], board[r][c] 43 lowest_zero -= 1 44 45 crushed_set = find() 46 while crushed_set: 47 crush(crushed_set) 48 drop() 49 crushed_set = find() 50 51 return board
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。