劍指 Offer 13. 機器人的運動範圍
阿新 • • 發佈:2020-08-01
劍指 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
BFS
class Solution: def movingCount(self, m: int, n: int, k: int) -> int: grid = [[0]*n for _ in range(m)] q = [[0,0]] count = 0 while q: x,y = q.pop(0) #如果沒有訪問過 並且和小於k 就可以進入 if grid[x][y] == 0 and sum(list(map(int,str(x)+str(y)))) <= k: count += 1 else: continue grid[x][y] = 1 for dx,dy in ([1,0],[0,1]): nx, ny = x+dx, y+dy if 0 <= nx < m and 0 <= ny <n: q.append([nx,ny]) return count
import java.util.*; class Solution { public int movingCount(int m, int n, int k) { // 建立佇列 Queue<int[]> queue = new LinkedList<int[]>(); int[][] grid = new int[m][n]; for (int i=0; i<m; i++){ for (int j=0;j<n;j++){ grid[i][j] = 0; } } int count=0; queue.offer(new int[] {0,0}); int[] dx = {0,1}; int[] dy = {1,0}; while (!queue.isEmpty()){ int cor[] = queue.poll(); int x = cor[0], y = cor[1]; if (grid[x][y] == 0 && digitSum(x,y) <= k){ count += 1; }else{ continue; } grid[x][y] = 1; for (int i=0;i<2;i++){ int nx = x+dx[i]; int ny = y+dy[i]; if (nx>=0 && nx<m && ny>=0 && ny <n){ queue.offer(new int[] {nx,ny}); } } } return count; } // 數位求和方法 int digitSum(int x, int y){ int sum = 0; while (x !=0 || y != 0){ sum = sum + x%10 + y%10; x = x/10; y = y/10; } return sum; } }
DFS
python版一
class Solution:
def movingCount(self, m: int, n: int, k: int) -> int:
def digitSum(x,y):
ans = 0
while x or y:
ans = ans+ x%10 + y%10
x, y = x//10,y//10
return ans
def dfs(x,y):
#遞迴結束條件
if x<0 or x>=m or y<0 or y>=n or grid[x][y]==1 or digitSum(x,y) > k:
return 0
grid[x][y] = 1
self.count += 1
dfs(x+1,y)
dfs(x,y+1)
grid = [[0]*n for _ in range(m)]
self.count = 0
dfs(0,0)
return self.count
python版二
class Solution:
def movingCount(self, m: int, n: int, k: int) -> int:
def digitSum(x,y):
ans = 0
while x or y:
ans = ans+ x%10 + y%10
x, y = x//10,y//10
return ans
def dfs(x,y):
#遞迴結束條件
if x<0 or x>=m or y<0 or y>=n or grid[x][y]==1 or digitSum(x,y) > k:
return 0
grid[x][y] = 1
return 1 + dfs(x+1,y) + dfs(x,y+1)
grid = [[0]*n for _ in range(m)]
return dfs(0,0)
java遞迴版
import java.util.*;
class Solution {
int m,n,k;
boolean[][] grid;
public int movingCount(int m, int n, int k) {
this.m = m; this.n = n; this.k = k;
grid = new boolean[m][n];
return dfs(0,0);
}
int dfs(int x, int y){
//遞迴結束條件
if(x<0 || x>= m || y<0 || y>=n || grid[x][y]==true || digitSum(x,y) >k){
return 0;
}
grid[x][y] = true;
return 1 + dfs(x+1,y) + dfs(x,y+1);
}
int digitSum(int x, int y){
int sum = 0;
while (x !=0 || y != 0){
sum = sum + x%10 + y%10;
x = x/10;
y = y/10;
}
return sum;
}
}
java棧
import java.util.*;
class Solution {
public int movingCount(int m, int n, int k) {
Stack<int[]> stack = new Stack<int[]>();
stack.push(new int[] {0,0});
int count = 0;
boolean[][] grid = new boolean[m][n];
int[] dx = {1,0};
int[] dy = {0,1};
while(!stack.isEmpty()){
int[] temp = stack.pop();
int x = temp[0];
int y = temp[1];
//滿足條件就加一
if (x>=0 && x<m && y>=0 && y <n && grid[x][y] == false && digitSum(x,y) <= k){
count += 1;
}else{
continue;
}
grid[x][y] = true;
for(int i=0;i<2;i++){
int nx = x+dx[i];
int ny = y+dy[i];
stack.push(new int[] {nx,ny});
}
}
return count;
}
int digitSum(int x, int y){
int sum = 0;
while (x !=0 || y != 0){
sum = sum + x%10 + y%10;
x = x/10;
y = y/10;
}
return sum;
}
}