[LeetCode] Candy Crush 糖果消消乐
This question is about implementing a basic elimination algorithm for Candy Crush.
Given a 2D integer array board
representing the grid of candy, different positive integers board[i][j]
represent different types of candies. A value of board[i][j] = 0
represents that the cell at position (i, j)
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 (ie. the board is stable), then return the current board.
You need to perform the above rules until the board becomes stable, then return the current 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]]
Explanation:
Note:
- The length of
board
will be in the range [3, 50]. - The length of
board[i]
will be in the range [3, 50]. - Each
board[i][j]
will initially start as an integer in the range [1, 2000].
这道题就是糖果消消乐,博主刚开始做的时候,没有看清楚题意,以为就像游戏中的那样,每次只能点击一个地方,然后消除后糖果落下,这样会导致一个问题,就是原本其他可以消除的地方在糖果落下后可能就没有了,所以博主在想点击的顺序肯定会影响最终的 stable 的状态,可是题目怎么没有要求返回所剩糖果最少的状态?后来发现,其实这道题一次消除 table 中所有可消除的糖果,然后才下落,形成新的 table,这样消除后得到的结果就是统一的了,这样也大大的降低了难度。下面就来看如何找到要消除的糖果,可能有人会觉得像之前的岛屿的题目一样找连通区域,可是这道题的有限制条件,只有横向或竖向相同的糖果数达到三个才能消除,并不是所有的连通区域都能消除,所以找连通区域不是一个好办法。最好的办法其实是每个糖果单独检查其是否能被消除,然后把所有能被删除的糖果都标记出来统一删除,然后在下落糖果,然后再次查找,直到无法找出能够消除的糖果时达到稳定状态。好,用一个数组来保存可以被消除的糖果的位置坐标,判断某个位置上的糖果能否被消除的方法就是检查其横向和纵向的最大相同糖果的个数,只要有一个方向达到三个了,当前糖果就可以被消除。所以对当前糖果的上下左右四个方向进行查看,用四个变量 x0, x1, y0, y1,其中 x0 表示上方相同的糖果的最大位置,x1 表示下方相同糖果的最大位置,y0 表示左边相同糖果的最大位置,y1 表示右边相同糖果的最大位置,均初始化为当前糖果的位置,然后使用 while 循环向每个方向遍历,注意并不需要遍历到尽头,而是只要遍历三个糖果就行了,因为一旦查到了三个相同的,就说明当前的糖果已经可以消除了,没必要再往下查了。查的过程还要注意处理越界情况,好,得到了上下左右的最大的位置,分别让相同方向的做差,如果水平和竖直方向任意一个大于3了,就说明可以消除,将坐标加入数组 del 中。注意这里一定要大于3,是因为当发现不相等退出 while 循环时,坐标值已经改变了,所以已经多加了或者减了一个,所以差值要大于3。遍历完成后,如果数组 del 为空,说明已经 stable 了,直接 break 掉,否则将要消除的糖果位置都标记为0,然后进行下落处理。下落处理实际上是把数组中的0都移动到开头,那么就从数组的末尾开始遍历,用一个变量t先指向末尾,然后然后当遇到非0的数,就将其和t位置上的数置换,然后t自减1,这样t一路减下来都是非0的数,而0都被置换到数组开头了,参见代码如下:
class Solution {
public:
vector<vector<int>> candyCrush(vector<vector<int>>& board) {
int m = board.size(), n = board[].size();
while (true) {
vector<pair<int, int>> del;
for (int i = ; i < m; ++i) {
for (int j = ; j < n; ++j) {
if (board[i][j] == ) continue;
int x0 = i, x1 = i, y0 = j, y1 = j;
while (x0 >= && x0 > i - && board[x0][j] == board[i][j]) --x0;
while (x1 < m && x1 < i + && board[x1][j] == board[i][j]) ++x1;
while (y0 >= && y0 > j - && board[i][y0] == board[i][j]) --y0;
while (y1 < n && y1 < j + && board[i][y1] == board[i][j]) ++y1;
if (x1 - x0 > || y1 - y0 > ) del.push_back({i, j});
}
}
if (del.empty()) break;
for (auto a : del) board[a.first][a.second] = ;
for (int j = ; j < n; ++j) {
int t = m - ;
for (int i = m - ; i >= ; --i) {
if (board[i][j]) swap(board[t--][j], board[i][j]);
}
}
}
return board;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/723
参考资料:
https://leetcode.com/problems/candy-crush/
https://leetcode.com/problems/candy-crush/discuss/178366/Another-Java-Solution
https://leetcode.com/problems/candy-crush/discuss/109225/Simple-C%2B%2B-brute-force
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Candy Crush 糖果消消乐的更多相关文章
- [LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现
[LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现 原题: There are N children standing in a line. ...
- [LeetCode] 723. Candy Crush 糖果消消乐
This question is about implementing a basic elimination algorithm for Candy Crush. Given a 2D intege ...
- [LeetCode] 723. Candy Crush 糖果粉碎
This question is about implementing a basic elimination algorithm for Candy Crush. Given a 2D intege ...
- [LeetCode] Candy 分糖果问题
There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...
- 消消乐、candy crush类三消游戏程序逻辑分析
最近在开发一款类似消消乐的三消游戏,在碰到实现斜方向下落的时候卡住了很长时间.好几天没有思路,原本的思路是一次性预判多个宝石的一连串运动路径,运用缓动运动队列来实现宝石运动路径,例如 下落->滑 ...
- 【LeetCode】723. Candy Crush 解题报告 (C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力 日期 题目地址:https://leetcode ...
- net.sz.framework 框架 ORM 消消乐超过亿条数据排行榜分析 天王盖地虎
序言 天王盖地虎, 老婆马上生孩子了,在家待产,老婆喜欢玩消消乐类似的休闲游戏,闲置状态,无聊的分析一下消消乐游戏的一些技术问题: 由于我主要是服务器研发,客户端属于半吊子,所以就分析一下消消乐排行榜 ...
- RSP小组——消消乐
RSP小组--消消乐 团队所有博客总结 1.团队第一周作业 2.团队第二周作业 3.RSP小组--团队冲刺博客一 4.RSP小组--团队冲刺博客二 5.RSP小组--团队冲刺博客三 6.RSP小组-- ...
- PHP实现开心消消乐的算法示例
本文主要介绍了关于PHP如何实现我们大家都知道的开心消消乐的算法,分享PHP教程出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一.需求描述: 1.在一个8*8的矩阵方格中随机 ...
随机推荐
- Angular开发实践(六):服务端渲染
Angular Universal Angular在服务端渲染方面提供一套前后端同构解决方案,它就是 Angular Universal(统一平台),一项在服务端运行 Angular 应用的技术. 标 ...
- 初始配置JDK
什么是java? java是一门编程语言 编程语言有很多种 你比如 C语言 等等 为什么学习java呢! 因为你要和计算机交互 当然了你用汉语跟她说她听不懂 所以你要学习编程语言 那么额咱们的ja ...
- Java基础学习笔记总结
Java基础学习笔记一 Java介绍 Java基础学习笔记二 Java基础语法之变量.数据类型 Java基础学习笔记三 Java基础语法之流程控制语句.循环 Java基础学习笔记四 Java基础语法之 ...
- C语言博客作业——函数
一.PTA实验作业 题目1:6-6 使用函数输出水仙花数 1.本题PTA提交列表 2. 设计思路 int narcissistic( int number ) //函数定义 1.定义整数型变量a.i分 ...
- C语言作业--数组
一.PTA实验作业 题目1:7-5 数组循环左移 1. 本题PTA提交列表 2. 设计思路 定义俩个整数 n,m 定义循环变量i,j,x 定义变量k用来存放下标 定义变量number用于交换数值 定义 ...
- C语言博客-指针
一.PTA实验作业(5分) 题目1:6-1 两个4位正整数的后两位互换 1. 本题PTA提交列表 2. 设计思路 3.代码截图 4.本题调试过程碰到问题及PTA提交列表情况说明. 无 题目2:6-3 ...
- 实验三《Java面向对象程序设计》实验报告
20162308 实验三<Java面向对象程序设计>实验报告 实验内容 XP基础 XP核心实践 IDEA工具学习 密码学算法基础 实验步骤 (一)Refactor/Reformat使用 p ...
- 网络1712--c语言字符数组作业总结..
---恢复内容开始--- 作业亮点 1.总体情况 1.大部分同学利用了流程图后,对于思路的理解有了提升. 2.很多同学在总结方面写的很不错,能够罗列问题贴出解决问题,我们能够看到你们的进步 2.作业发 ...
- QTableView
QTableView常用于实现数据的表格显示.下面我们如何按步骤实现学生信息表格: 一 添加表头 //准备数据模型 QStandardItemModel *student_model = ne ...
- python简单路由系统
# 输入模块名/函数 url = input('请输入网址:') module,func = url.split('/') m = __import__('lib.'+module,fromlist= ...