[LeetCode] 723. 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
boardwill 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] 723. Candy Crush 糖果消消乐的更多相关文章
- [LeetCode] 723. Candy Crush 糖果粉碎
This question is about implementing a basic elimination algorithm for Candy Crush. Given a 2D intege ...
- LeetCode 723. Candy Crush
原题链接在这里:https://leetcode.com/problems/candy-crush/ 题目: This question is about implementing a basic e ...
- [LeetCode] Candy Crush 糖果消消乐
This question is about implementing a basic elimination algorithm for Candy Crush. Given a 2D intege ...
- 【LeetCode】723. Candy Crush 解题报告 (C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力 日期 题目地址:https://leetcode ...
- 消消乐、candy crush类三消游戏程序逻辑分析
最近在开发一款类似消消乐的三消游戏,在碰到实现斜方向下落的时候卡住了很长时间.好几天没有思路,原本的思路是一次性预判多个宝石的一连串运动路径,运用缓动运动队列来实现宝石运动路径,例如 下落->滑 ...
- net.sz.framework 框架 ORM 消消乐超过亿条数据排行榜分析 天王盖地虎
序言 天王盖地虎, 老婆马上生孩子了,在家待产,老婆喜欢玩消消乐类似的休闲游戏,闲置状态,无聊的分析一下消消乐游戏的一些技术问题: 由于我主要是服务器研发,客户端属于半吊子,所以就分析一下消消乐排行榜 ...
- RSP小组——消消乐
RSP小组--消消乐 团队所有博客总结 1.团队第一周作业 2.团队第二周作业 3.RSP小组--团队冲刺博客一 4.RSP小组--团队冲刺博客二 5.RSP小组--团队冲刺博客三 6.RSP小组-- ...
- PHP实现开心消消乐的算法示例
本文主要介绍了关于PHP如何实现我们大家都知道的开心消消乐的算法,分享PHP教程出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一.需求描述: 1.在一个8*8的矩阵方格中随机 ...
- C#期末大作业 消消乐 2017-06-01 18:11 275人阅读 评论(0) 收藏
邻近期末,忙于刷题之余意识到期末大作业来不及了,匆匆赶下了作业,虽说做的很是粗糙,但完全原创的 下载链接 https://pan.baidu.com/s/1cCNLr4 大体的做大约3天完成了: 第一 ...
随机推荐
- tensor 中mul_,add_解读
pytorch 中文网文档链接 https://ptorch.com/docs/1/Tensor 每一个张量tensor都有一个相应的torch.Storage保存其数据,张量类提供了一个多维的,横向 ...
- kali渗透综合靶机(十五)--Breach-1.0靶机
kali渗透综合靶机(十五)--Breach-1.0靶机 靶机下载地址:https://download.vulnhub.com/breach/Breach-1.0.zip 一.主机发现 1.netd ...
- Log4基本配置
前言:作为一个程序员你要学会调试,对于一种调试都无法找到问题所在的情况,你要学会看日志,要学会看日志你的学会怎么样去写入日志,接下来教你配置C#Log4 第一步,你的在配置文件中配置好对应的参数 &l ...
- MyBatis面试题集合,90%会遇到这些问题
1.#{}和${}的区别是什么? ${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc. ...
- Flask笔记:session
session与cookie: cookie是一项浏览器的技术,而不是服务器的技术,服务器端是无法直接操作cookie的,只能通过返回Response响应告诉浏览器怎么操作cookie.而sessio ...
- 进程调度算法spf,fpf,时间片轮转算法实现
调度的基本概念:从就绪队列中按照一定的算法选择一个进程并将处理机分配给它运行,以实现进程并发地执行. 进程信息 struct node { string name;//进程名称 int id;//进程 ...
- jQuery 选择器有61种你都知道了多少
下面列举了61种jQuery 选择器 参考 选择器 语句 描述 * $("*") 选择所有元素 #id $("#lastname") id=“lastname” ...
- 面向对象的六大原则之 单一职责原则——SRP
SRP = Single Responsibility Principle 定义:就一个类而言,应该只有一个能引起他变化的原因.通俗的说,即一个类只负责一项职责. 作用: 1.减少了类之间的耦 ...
- Python3的sorted
排序算法 排序也是在程序中经常用到的算法.无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小.如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的 ...
- 基于记忆性的中值滤波O(r)与O(1)复杂度的算法实现
本文参考博客:https://www.cnblogs.com/Imageshop/archive/2013/04/26/3045672.html 原生的中值滤波是基于排序算法的,这样的算法复杂度基本在 ...