题目描述

这个问题是实现一个简单的消除算法。

给定一个二维整数数组 board 代表糖果所在的方格,不同的正整数 board[i][j] 代表不同种类的糖果,如果 board[i][j] = 0 代表 (i, j) 这个位置是空的。给定的方格是玩家移动后的游戏状态,现在需要你根据以下规则粉碎糖果,使得整个方格处于稳定状态并最终输出。

如果有三个及以上水平或者垂直相连的同种糖果,同一时间将它们粉碎,即将这些位置变成空的。
    在同时粉碎掉这些糖果之后,如果有一个空的位置上方还有糖果,那么上方的糖果就会下落直到碰到下方的糖果或者底部,这些糖果都是同时下落,也不会有新的糖果从顶部出现并落下来。
    通过前两步的操作,可能又会出现可以粉碎的糖果,请继续重复前面的操作。
    当不存在可以粉碎的糖果,也就是状态稳定之后,请输出最终的状态。

你需要模拟上述规则并使整个方格达到稳定状态,并输出。

样例 :

输入:
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]]

输出:
[[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]]

注释 :

board 数组的行数区间是 [3, 50]。
    board[i] 数组的长度区间(即 board 数组的列数区间)是 [3, 50]。
    每个 board[i][j] 初始整数范围是 [1, 2000]。

算法分析

方法:特殊用途的网络 Ad-Hoc [Accepted]

我们需要模拟执行所描述的算法。它由两个主要步骤组成:粉碎糖果和掉落糖果。我们每个步骤都是单独完成的。

算法:

粉碎糖果

我们如果是按行或者列进行粉碎,那么在粉碎的过程中可能会粉碎到其他行或列的需要粉碎糖果的一部分。如果 board 是:

123
145
111

那么我们如果先粉碎了第一列的 1 糖果,那么就会影响第三行 1 糖果的粉碎。

为了解决这个问题,我们可以先把要粉碎的糖果做个标记。我们可以使用 toCrush 布尔数组来辅助,或者我们可以将糖果标记为相反数(例如,board[i][j] = -Math.abs(board[i][j]))。

扫描 board 有两个方法。让我们把 line 称为 board 的行或列。

对于每一 line,我们可以使用一个滑动窗口(或者 Python 中的 itertools.groupby)来查找相同字符的连续段。如果段的长度大于 3,那么就应该标记它。

或者,对于每一 line,我们可以查看每一 line 的 width-3 段(一段为 3 个):如果它们都相同,那么我们应该标记这 3 个。

之后,将有标记的位置设置为 0 来粉碎糖果。

掉落糖果

对于每一列,我们希望所有的糖果都放在底部。一种方法是顺序遍历列中为粉碎的糖果放到栈中,然后以相反的顺序遍历列且弹出栈元素设置糖果。

或者,我们可以使用滑动窗口方法,read 指针读元素,write 指针写元素。指针以逆序遍历列元素,当 read 指针遇到糖果时,write 指针将它写下来并移动到下一个位置。然后,write 指针将向列的其余部分写入零。

代码

class Solution {
public:vector<vector<int>> candyCrush(vector<vector<int>>& board) {int row = board.size();int col = board[0].size();bool todo = false;// 遍历行for(int r = 0; r < row; ++r) {for(int c = 0; c < col - 2; ++c) {int v = abs(board[r][c]);if(v != 0 && v == abs(board[r][c+1]) && v == abs(board[r][c+2])) {board[r][c] = board[r][c+1] = board[r][c+2] = -v;todo = true;}}}// 遍历列for(int c = 0; c < col; ++c) {for(int r = 0; r < row - 2; ++r) {int v = abs(board[r][c]);if(v != 0 && v == abs(board[r+1][c]) && v == abs(board[r+2][c])) {board[r][c] = board[r+1][c] = board[r+2][c] = -v;todo = true;}}}if(todo) {for(int c = 0; c < col; ++c) {int row_down = row - 1;for(int r = row -1; r >= 0; --r) {if(board[r][c] > 0) {board[row_down][c] = board[r][c];--row_down;}}while(row_down >= 0) {board[row_down][c] = 0;--row_down;}}}return todo ? candyCrush(board) : board;}
};

时间复杂度分析

时间复杂度:O((RC)^2)。其中 R,C 指的是 board 的行和列。
空间复杂度:O(1),因为在 board 进行原地修改。

双指针——粉碎糖果(leetcode 723)相关推荐

  1. LeetCode 723. 粉碎糖果(模拟)

    文章目录 1. 题目 2. 解题 1. 题目 这个问题是实现一个简单的消除算法. 给定一个二维整数数组 board 代表糖果所在的方格,不同的正整数 board[i][j] 代表不同种类的糖果,如果 ...

  2. 【LeetCode - 723】粉碎糖果

    文章目录 1.题目描述 2.解题思路 3.解题代码 1.题目描述 2.解题思路   本题主要有两个步骤:找出需要粉碎的糖果所在的格子.粉碎糖果.   定义一个变量 todo 作为是否需要粉碎的标记. ...

  3. 【重点:DP 双指针 栈】LeetCode 42. Trapping Rain Water

    LeetCode 42. Trapping Rain Water 本博客转载自:http://www.cnblogs.com/grandyang/p/4402392.html [自己又不会做,抄的-& ...

  4. LeetCode+ 16 - 20 双指针、排序|暴搜、递归|双指针、排序|链表|栈、字符串

    最接近的三数之和 算法标签:数组.双指针.排序 LeetCode+ 11 - 15 给你一个长度为 n 的整数数组 nums 和 一个目标值 target.请你从 nums 中选出三个整数,使它们的和 ...

  5. 双指针(Double Pointer)

    双指针 [209. 长度最小的子数组](https://leetcode.cn/problems/minimum-size-subarray-sum/) [713. 乘积小于 K 的子数组](http ...

  6. 【Leetcode】精选算法top200道(二)

    二.中等 339.嵌套列表权重和 给定一个嵌套的整数列表 nestedList ,每个元素要么是整数,要么是列表.同时,列表中元素同样也可以是整数或者是另一个列表. 整数的 深度 是其在列表内部的嵌套 ...

  7. LeetCode(1-200)

    目录 LeetCode 1. 两数之和 LeetCode 2. 两数相加 LeetCode 3. 无重复字符的最长子串 LeetCode 4. 寻找两个正序数组的中位数 LeetCode 5. 最长回 ...

  8. LeetCode题解目录

    最新更新于2020.11.27 前往LeetCode主页. 前往GitHub源码.(服务器原因,暂停同步.) 前往码云主页. 已解决 456/1878 - 简单353 中等 90 困难 13 2020 ...

  9. LeetCode部分刷题笔记!!!JavaScript!!!

    详细解说请看视频JS老毕:人人都能看得懂的Leetcode力扣刷题教程合集 边看视频边记录笔记!!!部分题目在视频中无! 文章目录 LeetCode第1题:1. 两数之和 LeetCode第2题:2. ...

最新文章

  1. ip pim spare 源树 和 共享树_iPhone通过内置应用与电脑传输共享文件指南
  2. hdu 1757 矩阵连乘
  3. inline「一」:从 image 底部白边初识 line-height
  4. java setlocation_Java Point.setLocation方法代碼示例
  5. WEB安全基础-URL跳转漏洞
  6. Java 设计模式之构造者模式
  7. Linux内核相关书籍
  8. SQL vs NoSQL:异同比较
  9. 将项目打成war包并用tomcat部署的方法,步骤及注意点
  10. EF Core 小工具
  11. 深度学习12-TFRecord详解
  12. paip.python错误解决23
  13. Linux使用信号量监控程序异常退出
  14. pythonffmpeg 推流_ffmpeg推流和播放命令
  15. Python学习笔记(10)——舆情数据评分系统搭建
  16. Java工程师待遇怎么样?
  17. 查询成绩第三名的学生信息
  18. [2020首届祥云杯]带音乐家
  19. Linux:CentOS7安装
  20. 开源机器学习流水线(Pipeline)工具调研(MLOps)

热门文章

  1. 年终固定资产大盘点的解决方案
  2. 建立基于Equinox的OSGi编译与调试环境
  3. stm32mp157系统移植 | 移植ST官方5.10内核到小熊派开发板
  4. 坦克大战C++无敌版
  5. 禅道测试套件怎么用_易软快报第40期:禅道新增测试套件、报告、用例库功能...
  6. 内容分发技术哪家强?内容分发技术平台都有哪些
  7. perl dbi mysql 参数_Perl数据库DBI接口简介【转载】
  8. Python2.7获取QQ好友头像
  9. 无锡ISO特气供应气站消防设备电源监控的设计与应用
  10. cherry键盘维修记