34.矩阵中的路径
题目:
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母 不允许被重复使用。
题解:
- 对 二维数组 board 进行遍历,寻找word的首字母,以此为起点进行深度优先搜索;
- 注意:双重循环中,不能用
return dfs(board, chars, i, j, 0)
代替if(dfs(board, chars, i, j, 0)) return true;
因为二位数组中可能存在多个word的首字母,即多个DFS的入口。
- 注意:双重循环中,不能用
- 递归函数
dfs
- 如果 下标越界 或者 当前元素board [i] [j]不等于word[k] ,返回false;
- 如果函数继续执行则代表 当前元素board [i] [j]等于word[k] ,此时如果
k == chars.length - 1
,即当前元素等于word的尾字母,即遍历结束,返回true; - 如果是word的中间字母,则将该元素使用
board[a][b] = '\0';
语句进行覆盖,继续递归遍历其上下左右元素; - 一定注意 递归结束之后,要将被覆盖的元素使用
board[a][b] = chars[k];
进行复原,要保证下一次进行DFS时,二维数组是初始状态。
public boolean exist(char[][] board, String word) {
char[] chars = word.toCharArray();
for (int i = 0; i < board.length; i++){
for (int j = 0; j < board[0].length; j++){
if(dfs(board, chars, i, j, 0)) return true;
}
}
return false;
}
boolean dfs(char[][] board, char[] chars, int a, int b, int k){
if (a < 0 || b < 0 || a >= board.length || b >= board[0].length || board[a][b] != chars[k]) return false;
if (k == chars.length - 1) return true;
board[a][b] = '\0';
boolean res = dfs(board, chars, a, b - 1,k+1) || dfs(board,chars,a + 1, b,k+1) || dfs(board, chars, a - 1,b, k+1) || dfs(board, chars, a, b + 1,k+1);
board[a][b] = chars[k];
return res;
}
35.机器人的运动范围
题目:
地上有一个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。请问该机器人能够到达多少个格子?
题解:
- 使用
boolean[][] visited
来表示该位置是否被访问,初始化全部为false,被访问后设置为true; - 递归函数
dfs
结束条件i
和j
越界;i
和j
的数位和si + sj
大于k
;visited[i][j]
为true ,即该位置被访问。
- 未达到递归结束条件
- 将visited数组该位置的元素置为true;
- 向下向右调用递归函数,注意 数位之和 的计算;
- 返回 1 + dfs(向下) + dfs(向右);
- 数位之和的计算
- 如果
(x+1)%10 == 0
,则数位之和-8
,比如x = 19,向下或者向右移动之后变为20,数位和由10变为了2; - 如果
(x+1)%10 != 0
,则数位之和+1
,比如x = 12,向下或者向右移动之后变为13,数位和由3变为了4。
- 如果
class Solution {
int row,column,k;
boolean[][] visited;
public int movingCount(int m, int n, int k) {
row = m; column = n; this.k = k;
this.visited = new boolean[m][n];
return dfs(0,0,0,0);
}
int dfs (int i, int j, int si, int sj){
if (i > row - 1 || j > column - 1 || si + sj > k || visited[i][j]) return 0;
visited[i][j] = true;
return 1 + dfs(i + 1, j,(i + 1) % 10 == 0 ? si - 8 : si + 1, sj) + dfs(i,j + 1, si, (j + 1) % 10 == 0 ? sj - 8: sj + 1);
}
}
他心里又一次因为别人的命运而暗自忧伤了。