【剑指Offer 13】机器人的运动范围
深度优先
/**
* 剑指 Offer 13. 机器人的运动范围
* https://leetcode.cn/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/
*
* 思路:深度优先
* */
public class Solution1 {
private boolean[][] marked;
private int m;
private int n;
private int k;
public int movingCount(int m, int n, int k) {
this.m = m;
this.n = n;
this.k = k;
marked = new boolean[m][n];
return dfs(0, 0);
}
private int dfs(int i, int j) {
if (i < 0 || i >= m || j < 0 || j >= n) {
return 0;
}
if (marked[i][j] || sum(i, j) > k) {
return 0;
}
marked[i][j] = true;
return dfs(i + 1, j)
+ dfs(i - 1, j)
+ dfs(i, j + 1)
+ dfs(i, j - 1)
+ 1;
}
private int sum(int i, int j) {
String num = String.valueOf(i) + String.valueOf(j);
int sum = 0;
for (int index = 0; index < num.length(); index++) {
sum += num.charAt(index) - '0';
}
return sum;
}
}
更高效地计算下标和:
if (marked[i][j] || sum(i) + sum(j) > k) {
return 0;
}
private int sum(int num) {
int sum = 0;
while (num > 0) {
sum += num % 10;
num /= 10;
}
return sum;
}
广度优先
/**
* 剑指 Offer 13. 机器人的运动范围
* https://leetcode.cn/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/
*
* 思路:广度优先
* */
public class Solution2 {
private int m;
private int n;
private int k;
private boolean[][] marked;
public int movingCount(int m, int n, int k) {
this.m = m;
this.n = n;
this.k = k;
marked = new boolean[m][n];
return bfs(0, 0);
}
private int bfs(int i, int j) {
Queue<int[]> queue = new ArrayDeque<>();
int count = add(queue, i, j);
while (!queue.isEmpty()) {
int[] point = queue.remove();
i = point[0];
j = point[1];
count += add(queue, i + 1, j)
+ add(queue, i - 1, j)
+ add(queue, i, j + 1)
+ add(queue, i, j - 1);
}
return count;
}
private int add(Queue<int[]> queue, int i, int j) {
if (i < 0 || i >= m || j < 0 || j >= n || marked[i][j] || sum(i) + sum(j) > k) {
return 0;
}
queue.add(new int[]{i, j});
marked[i][j] = true;
return 1;
}
private int sum(int num) {
int sum = 0;
while (num > 0) {
sum += num % 10;
num /= 10;
}
return sum;
}
}