题目描述:
这个问题是实现一个简单的消除算法。
给定一个二维整数数组 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]。
方法1:
主要思路:
(1)使用两个辅助函数,第一个find_pos函数用来找可以粉碎的糖果的位置,这里函数内将找行和列分开进行;
(2)第二个辅助函数updata用来将找到的需要粉碎的位置进行更新,获得新的数组组成;
(3)再重复调用这两个函数,直到第一个函数内找不到需要粉碎的位置;
class Solution {
public:
//找需要粉碎的位置
void find_pos(vector<vector<int>>& board,bool& sign){
//先在每行中找需要粉碎糖果的位置
for(int i=0;i<board.size();++i){
for(int j=0;j<board[0].size()-2;++j){
if(board[i][j]!=0){
int cur_pos=j;
while(cur_pos<board[0].size()&&board[i][cur_pos]==board[i][j]){
++cur_pos;
}
if(cur_pos-j>=3){//判断是否找到合适的需要粉碎的位置
sign=true;
while(j<cur_pos){//将需要粉碎的位置进行负数标识
board[i][j]=-board[i][j];
++j;
}
--j;
}
}
}
}
//再在每列中找需要粉碎糖果的位置
for(int i=0;i<board[0].size();++i){
for(int j=0;j<board.size()-2;++j){
if(board[j][i]!=0){
int cur_pos=j;
while(cur_pos<board.size()&&abs(board[cur_pos][i])==abs(board[j][i])){//上面在行中,已经使用了负数进行标识
++cur_pos;
}
if(cur_pos-j>=3){
sign=true;
while(j<cur_pos){
board[j][i]=-abs(board[j][i]);//将位置上的数字使用负数进行标识
++j;
}
--j;
}
}
}
}
}
//将标识的位置进行更细
void updata(vector<vector<int>>&board){
//对每列从下向上进行更新
for(int col=0;col<board[0].size();++col){
int cur_pos=board.size();
for(int row=board.size()-1;row>=0;--row){
if(board[row][col]>0){
board[--cur_pos][col]=board[row][col];
}
}
//将当前列的上面的位置进行赋值0
while(cur_pos>0){
board[--cur_pos][col]=0;
}
}
}
vector<vector<int>> candyCrush(vector<vector<int>>& board) {
bool sign=false;
while(true){
sign=false;
find_pos(board,sign);
if(!sign){//说明没再找到可以粉碎的位置,故需要跳出循环
break;
}
updata(board);
}
return board;
}
};