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

leetcode 劍指 Offer 13. 機器人的運動範圍

劍指 Offer 13. 機器人的運動範圍

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

示例 1:

輸入:m = 2, n = 3, k = 1
輸出:3

示例 2:

輸入:m = 3, n = 1, k = 0
輸出:1

提示:

1 <= n,m <= 100
0 <= k <= 20

思路:

dfs每次遍歷四個方向,沒有越界且行列數字之和小於等於k則遞迴遍歷它,否則跳過

 1 class Solution {
 2 
 3     // 獲取數字的數位之和
 4     public int getSumOfBit(int a){
 5         int sum = 0;
 6         while(a != 0){
 7             sum += a % 10;
 8             a /= 10;
 9         }
10         return sum;
11     }
12 
13     public boolean[][] vis; //
判斷是否遍歷過 14 public int m, n, k; // 記錄m,n,k,減少變數傳遞的開銷 15 public int cnt = 0; // 計數器,記錄能到達的格子數量 16 17 public int movingCount(int m, int n, int k) { 18 19 vis = new boolean[m][n]; 20 this.m = m; 21 this.n = n; 22 this.k = k; 23 24 // dfs遍歷 25 dfs(0, 0);
26 27 return cnt; 28 } 29 30 public int[][] dir = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; 31 32 public void dfs(int row, int col){ 33 vis[row][col] = true; 34 cnt++; 35 // 每次遍歷四個方向,沒有越界且行列數字之和小於等於k則遞迴遍歷它,否則跳過 36 for(int i = 0; i < 4; i++){ 37 int newRow = row + dir[i][0]; 38 int newCol = col + dir[i][1]; 39 if(newRow <m && newRow >= 0 && newCol < n && newCol >= 0 40 && (getSumOfBit(newRow) + getSumOfBit(newCol)) <= k && vis[newRow][newCol] == false){ 41 dfs(newRow, newCol); 42 } 43 } 44 } 45 }

leetcode執行時間為2ms, 空間為35.4MB

複雜度分析:

時間複雜度:每個單元格最多被遍歷一次,最壞情況下遍歷所有單元格,所以時間複雜度為O(n*m)

空間複雜度:需要一個大小為n*m的 vis[][]陣列記錄單元格是否被訪問過,遞迴也會有一個遞迴棧的複雜度,最大深度為max(m, n), 所以空間複雜度為O(n*m + max(m,n))