Candy Crush
public class Solution {
/**
* @param board: a 2D integer array
* @return: the current board
*/
public int[][] candyCrush(int[][] board) {
if (board == null || board.length == 0 || board[0].length == 0) return board;
boolean flag = true; // flag to indicate whether we need to proceed more
while (flag) {
flag = processRowsAndCols(board);
if (flag) dropCandies(board);
}
return board;
}
private boolean processRowsAndCols(int[][] board) {
int rows = board.length, cols = board[0].length;
boolean flag = false;
// process rows
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols -2; j++) {
int val = Math.abs(board[i][j]);
// mark the cells to negative val if they can be crushed
if (val != 0 && val == Math.abs(board[i][j + 1]) && val == Math.abs(board[i][j + 2])) {
board[i][j] = board[i][j + 1] = board[i][j + 2] = -val;
flag = true;
}
}
}
// process cols
for (int j = 0; j < cols; j++) {
for (int i = 0; i < rows - 2; i++) {
int val = Math.abs(board[i][j]);
if (val != 0 && val == Math.abs(board[i + 1][j]) && val == Math.abs(board[i + 2][j])) {
board[i][j] = board[i + 1][j] = board[i + 2][j] = -val;
flag = true;
}
}
}
return flag;
}
private void dropCandies(int[][] board) {
int rows = board.length, cols = board[0].length;
// 对每一列依次遍历
for (int j = 0; j < cols; j++) {
// 记录最下面一行,用来标记落下的正数需要更新到哪一行
int bottomRow = rows - 1;
// 对这一列的每一行,如果当前行的格子是正数,则需要下落(也可能就在同一行不变)
// 如果是负数,说明当前格子会被覆盖掉,所以跳过
for (int i = rows - 1; i >= 0; i--) {
if (board[i][j] > 0) {
// 把正数的格子下落
board[bottomRow][j] = board[i][j];
// 更新标记
bottomRow--;
}
}
// 在处理完这一列的每一行后,再把下落后上方的空位补成0
while (bottomRow >= 0) {
board[bottomRow][j] = 0;
bottomRow--;
}
}
}
}Last updated