Pointing to the Offer-Question 13 (Java Edition): The Robot's Range of Motion

Reference from: "Sword Pointing Offer - Famous Enterprise Interviewer Talking About Typical Programming Questions"

Question : The range of motion of
the robot There is a square with m rows and n columns on the ground. A robot starts to move from the grid of coordinates (0, 0), and it can move one grid to the left, right, up, and down at a time, but cannot enter the grid where the sum of the digits of the row and column coordinates is greater than k. For example, when k is 18, the robot can enter square (35, 37) because 3+5+3+7=18. But it cannot enter square (35, 38) because 3+5+3+8=19. How many squares can the robot reach?

The main idea : The backtracking method is mainly used. The robot starts to move from (0, 0), when the robot is ready to move to the coordinates (x, y), it first judges whether the coordinates meet the conditions, if so, it enters the grid, and then judges whether it can enter the adjacent grid.

Key points : backtracking, recursion

Time complexity : O(m*n)

public class MovingCount
{
    public static void main(String[] args)
    {
        int count = movingCount(5, 10, 10); //21
        System.out.println(count);

        int count1 = movingCount(15, 20, 20); //359
        System.out.println(count1);
    }

    private static int movingCount(int threshold, int rows, int cols)
    {
        if (threshold <= 0 || rows < 1 || cols < 1) return 0;
        boolean[][] visited = new boolean[rows][cols];
        return move(threshold, rows, cols, 0, 0, visited);
    }

    private static int move(int threshold, int rows, int cols,
                            int row, int col, boolean[][] visited)
    {
        int count = 0;
        if (canMove(threshold, rows, cols, row, col, visited))
        {
            visited[row][col] = true;
            //判断是否进入周围相邻格子
            count = 1 + move(threshold, rows, cols, row - 1, col, visited)
                    + move(threshold, rows, cols, row + 1, col, visited)
                    + move(threshold, rows, cols, row, col - 1, visited)
                    + move(threshold, rows, cols, row, col + 1, visited);
        }
        return count;
    }

    /**
     * 判断是否可以到达
     *
     * @param threshold
     * @param rows
     * @param cols
     * @param row
     * @param col
     * @param visited
     * @return
     */
    private static boolean canMove(int threshold, int rows, int cols,
                                   int row, int col, boolean[][] visited)
    {
        if (row >= 0 && row < rows && col >= 0 && col < cols
                && !visited[row][col])
        {
            //行和列的数位之和
            int digits = getDigits(row) + getDigits(col);
            return digits <= threshold;
        }
        return false;
    }

    /**
     * 获取数位之和
     * @param num
     * @return
     */
    private static int getDigits(int num)
    {
        int digits = 0;
        while (num != 0)
        {
            digits += num % 10;
            num /= 10;
        }
        return digits;
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325891055&siteId=291194637