剑指offer_ 机器人的运动范围

题目描述

地上有一个m行和n列的方格。一个机器人从坐标(0,0)的格子开始移动,每一次只能向左右上下四个方向移动一格,但是不能进入行坐标和列坐标的位数之和大于k的格子。

例如当k为18时,机器人能够进入放格(35,37),因为3+5+3+7=18,但是不能进入方格(35,38),因为3+5+3+8=19。请问该机器人能够达到多少个格子?

解题思路

使用深度优先搜索方法进行求解。回溯是深度优先搜索的一种特例,它在一次搜索过程种需要设置一些本次搜索过程的局部状态,并在本次搜索结束之后清除状态。而普通的深度优先搜索并不需要使用这些局部状态。

 1 public class Solution {
 2     
 3     private static final int [][] next = {{0,-1},{0,1},{-1,0},{1,0}};
 4     private int cnt=0;
 5     private int rows;
 6     private int cols;
 7     private int threshold;
 8     private int [][] digitSum;
 9     
10         
11     public int movingCount(int threshold, int rows, int cols)
12     {
13         this.rows=rows;
14         this.cols=cols;
15         this.threshold=threshold;
16         initDigitSum();
17         boolean [][] marked =new boolean [rows][cols];
18         dfs(marked,0,0);
19         return cnt; 
20     }
21     
22     private void dfs(boolean [][] marked, int r,int c){
23         if(r<0||r>=rows||c<0||c>=cols||marked[r][c]) return;
24         marked[r][c]=true;
25         if(this.digitSum[r][c]> this.threshold) return;
26         cnt++;
27         for (int [] n:next)
28             dfs(marked,r+n[0],c+n[1]);
29     }
30     
31     private void initDigitSum(){
32         int [] digitSumOne = new int [Math.max(rows,cols)];
33         for(int i=0;i< digitSumOne.length;i++){
34             int n=i;
35             while(n>0){
36                 digitSumOne[i]+=n%10;
37                 n/=10;
38             }
39         }
40         
41         this.digitSum = new int [rows][cols];
42         for(int i=0; i< this.rows;i++){
43             for(int j=0;j<this.cols;j++){
44                 this.digitSum[i][j]=digitSumOne[i]+digitSumOne[j];
45             }
46         }
47     }
48 
49 
50 
51 }

 

posted @ 2019-08-20 12:59  chyblogs  阅读(137)  评论(0)    收藏  举报