1. 程式人生 > 實用技巧 >劍指66.機器人的運動範圍

劍指66.機器人的運動範圍

題目描述

地上有一個m行和n列的方格。一個機器人從座標0,0的格子開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數位之和大於k的格子。 例如,當k為18時,機器人能夠進入方格(35,37),因為3+5+3+7 = 18。但是,它不能進入方格(35,38),因為3+5+3+8 = 19。請問該機器人能夠達到多少個格子?

思路

與《矩陣中的路徑》類似,但這道題不需要回溯,因為如果滿足條件一定可以走到。而《矩陣中的路徑》如果路徑走不通,需要回溯。

思路1:通過遞迴的去查詢某一個下標位置的兩個方向即可(要麼往右要麼往下),在到達某一個位置的時候,判斷是否越界,是否被訪問過,是否滿足數位之和小於k (最優解)

思路2:逐個遍歷每一個方格,判斷數位之和是否小於等於k,並且判斷當前位置能否由 上邊的位置 和 左邊的位置 走來即可。 (如果k=0時,仍需要不斷判斷,該方法效率較低)

☆☆解法1

public class Solution {
    private int sum = 0;
    public int movingCount(int threshold, int rows, int cols) {
        boolean[][] vis = new boolean[rows][cols];
        solve(0,0,rows,cols,threshold,vis);
        
return sum; } // 牢記如何求位數和!! private int cal(int num){ int res = 0; while (num > 0){ res += num % 10; num /= 10; } return res; } private void solve(int x, int y, int rows, int cols, int k, boolean[][] vis) { if (x < 0 || y < 0 || x >= rows || y >= cols || vis[x][y] || (cal(x) + cal(y) > k)){
return; } // 當前位置(x,y)是可以走的,那麼就從當前位置往右下移動即可。 vis[x][y] = true; sum++; solve(x,y+1,rows,cols,k,vis); // solve(x+1,y,rows,cols,k,vis); //// 既然不用回溯,就不需要遞迴x-1和y-1的座標了,因為從左上角出發,每次只需要往右和往下搜尋 // solve(x-1,y,rows,cols,k,vis); // solve(x,y-1,rows,cols,k,vis); } }

☆解法2

public class Solution {
    public int movingCount(int threshold, int rows, int cols) {
        int sum = threshold >= 0 ? 1 : 0;
        boolean[][] vis = new boolean[rows][cols];
        vis[0][0] = true;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if ((cal(i) + cal(j)) <= threshold){
                    // 判斷能否從上邊走過來
                    if (i-1 >= 0 && vis[i-1][j]){
                        sum++;
                        vis[i][j] = true;
                        // 判斷能否從左邊走過來
                    }else if (j-1 >= 0 && vis[i][j-1]){
                        sum++;
                        vis[i][j] = true;
                    }
                }
            }
        }
        return sum;
    }
    private int cal(int num){
        int res = 0;
        while (num > 0){
            res += num % 10;
            num /= 10;
        }
        return res;
    }
}