当前位置: 首页 > news >正文

723. Candy Crush

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:

  • If three or more candies of the same type are adjacent vertically or horizontally, crush them all at the same time - these positions become empty.
  • After crushing all candies simultaneously, if an empty space on the board has candies on top of itself, then these candies will drop until they hit a candy or bottom at the same time. No new candies will drop outside the top boundary.
  • After the above steps, there may exist more candies that can be crushed. If so, you need to repeat the above steps.
  • If there does not exist more candies that can be crushed (i.e., the board is stable), then return the current board.

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

Solution


Overview

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
  • crush
  • drop

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.

img


Approach 1: Separate Steps: Find, Crush, Drop

Intuition

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.

img

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.

img

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.

img

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.

img

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

img

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.

img

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

img


Algorithm

    1. Define find() to find all crushable candies:

      • Initialize an empty set crushed_set.
      • Iterate over each candy (r, c):
        • If board[r][c] = 0, continue.
        • If 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.
      • Return crushed_set.
    2. Define crush(crushed_set) to mark all crushable candies:

      • Iterate over every candy (r, c) in crushed_set and set board[r][c] = 0.
    3. Define drop() to rearrange the candies' new positions based on the rules:

      • Iterate over each column c.
      • For each column, set lowest_zero as -1 since there is no lowest zero yet.
      • Iterate candies (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.
    4. While find() returns an non-empty set crushed_set:

      • Perform crush(crushed_set).
      • Perform drop().
    5. 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                     elif lowest_zero >= 0:
41                         board[r][c], board[lowest_zero][c] = board[lowest_zero][c], board[r][c]
42                         lowest_zero -= 1
43 
44         crushed_set = find()
45         while crushed_set:
46             crush(crushed_set)
47             drop()
48             crushed_set = find()
49 
50         return board

 



http://www.zskr.cn/news/38050.html

相关文章:

  • 江湖人是过河卒 路是不归路 -- csp-s 2025 游记
  • 团队项目1-团队展示选题-星瀚餐递
  • DRL-SARSA
  • 团队作业1-团队展示与选题
  • 每日一题:第474场周赛 Q1. 找出缺失的元素
  • 上一次的参考文献
  • 思维的漫游者:叙事性所揭示的非目的性心智
  • 软件技术基础
  • 【UE引擎解构】- 引擎基础 :基本组件
  • 视频瘦身大师
  • 如何把应用程序的图标都摆在xfce的panel上
  • 团队作业
  • 每日反思(2025_11_02)
  • 第二章数字的表示和运算
  • 利用XPlaneConnect从X-Plane内读写数据
  • fastdbchkrep项目(数据库自动生成巡检报告) open source
  • nginx入门-server基础
  • Typora使用命令
  • 免费智普大模型调用
  • 嵌入式C语言寄存器操作
  • PC 指针为何不等于执行地址?
  • VIM使用教程
  • sqli-labs_less8 布尔盲注脚本
  • ST产品型号解析
  • conda使用记录
  • 题解:P4895 独钓寒江雪
  • 题解:CF1037E Trips
  • 题解:CF387E George and Cards
  • 题解:CF712D Memory and Scores
  • 拾壹月贰