LeetCode: Candy Crush



Today's question is asked commonly at Bloomberg, many times and it represents the Candy Crush Algorithm for the elimination algorithm. 

Given a 2D integer array, board, representing a grid of candy, different positive integers board[i][j] represent different types of candies. If board[i][j] is equivalent to 0, this means the cell at the position (i, j) is empty. We need to restore the candy crush into a stable state. People say it's an implementation-heavy problem, but we'll still decipher it with these instructions:

1. If 3 or more candies of the same type are adjacent vertically or horizontally, "crush" them all at the same time, and these positions become empty. 

2. After crushing all the candies, if the empty space on the board has candies, the candies will drop until they hit the bottom at the same time.

3. After there may be more candies that can be crushed

4. Return the board when no more candies are able to be crushed. 

Perform these rules until the board becomes stable, then return the current board. We need to carefully perform the "crush" and "gravity" steps as a result. 

Append the difference between the first row and the last row, and append zeroes after that, which is the main key to this problem. We crush horizontally first. Then, we crush vertically, and finally, we drop vertically to solve this problem. Jeantimex has a good solution for this problem here.

Here's the code:

public int[][] candyCrush(int[][] board) {

    int m = board.length;

    int n = board[0].length;

    boolean shouldContinue = false;

    //crush the board horizontally

    for(int i = 0; i < m; i++) {

        for(int j = 0; j < n - 2; j++) {

            int v = Math.abs(board[i][j]);

            if(v > 0 && v == Math.abs(board[i][j + 1])  && v == Math.abs(board[i][j + 2])) {

                //negative the board side with horizontal orientations

                board[i][j] = board[i][j + 1] =  board[i][j + 2] = -v;

                shouldContinue = true;

            }

        }

    }

    //crush the board vertically

    for(int i = 0; i < m - 2; i++) {

        for(int j = 0; j < n; j++) {

            int v = Math.abs(board[i][j]); 

            if(v > 0 && v == Math.abs(board[i + 1][j] && v == Math.abs(board[i + 2][j])) {

                //negative the board side with vertical orientations 

                board[i][j] = board[i + 1][j] = board[i + 2][j] = -v;

                shouldContinue = true;

            }

        }

    }

    //drop the board vertically while pushing  the variable i close up in the other direction. 

    for(int j = 0; j < n; j++) {

        int r = m - 1;

        for(int i = m - 1; i >= 0; i--) {

            if(board[i][j] >= 0) {

                board[r--][j] = board[i][j];

            }

        }

        for(int i = r; i >= 0; i--) {

            board[i][j] = 0;

        }

    }

    return shoudContinue ? candyCrush(board) : board;

}

Comments

Popular Posts