public class JZ6601 {
private final static int[][] next={{0,1},{0,-1},{1,0},{-1,0}};
private int cnt=0;
private int rows;
private int cols;
private int threshold;
private int[][] digitSum;
public int movingCount(int threshold, int rows, int cols) {
this.rows=rows;
this.cols=cols;
this.threshold=threshold;
initDigitSum();
boolean[][] marked=new boolean[rows][cols];
dfs(marked,0,0);
return cnt;
}
private void dfs(boolean[][] marked,int r,int c){
if(r<0||r>=rows||c<0||c>=cols||marked[r][c])
return;
marked[r][c]=true;
if(this.digitSum[r][c]>this.threshold){
return;
}
cnt++;
for(int[] n:next){
dfs(marked,r+n[0],r+n[1]);
}
}
public void initDigitSum(){
int[] digitSumOne=new int[Math.max(rows,cols)];
for(int i=0;i<digitSumOne.length;i++){
int n=i;
while(n>0){
digitSumOne[i]+=n%10;
n/=10;
}
}
this.digitSum=new int[rows][cols];
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
digitSum[i][j]=digitSumOne[i]+digitSumOne[j];
}
}
}
}
使用深度优先算法(dfs),不断向下递归求解,直到遇到边界条件再进行回溯。
import java.util.*;
public class Solution {
private int[][] digitSum;
private int rows;
private int cols;
public int movingCount(int threshold, int rows, int cols) {
boolean[][] marked=new boolean[rows][cols];
int res=0;
this.rows=rows;
this.cols=cols;
initDigitSum();
Queue<int[]> queue=new LinkedList<>();
queue.add(new int[]{0,0});
while(queue.size()>0){
int[] temp=queue.poll();
int i=temp[0],j=temp[1];
if(i>=rows||j>=cols||threshold<digitSum[i][j]||marked[i][j])
continue;
marked[i][j]=true;
res++;
//不需要向上向左遍历
queue.add(new int[]{i+1,j});
queue.add(new int[]{i,j+1});
}
return res;
}
public void initDigitSum(){
int[] digitSumOne=new int[Math.max(rows,cols)];
for(int i=0;i<digitSumOne.length;i++){
int n=i;
while(n>0){
digitSumOne[i]+=n%10;
n/=10;
}
}
this.digitSum=new int[rows][cols];
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
digitSum[i][j]=digitSumOne[i]+digitSumOne[j];
}
}
}
}
使用广度优先算法(BFS),用队列保存遍历相邻格子的坐标,根据队列先进先出的特点,优先遍历了相邻格子;用矩阵digitSum来保存坐标数字相加的值。