723粉碎糖果

it2023-01-13  52

题目描述: 这个问题是实现一个简单的消除算法。 给定一个二维整数数组 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; } };
最新回复(0)