今天的题刚做还挺有难度的,但是大差不差,能记住这种套路解决搜索与回溯问题就行。
思路:dfs+回溯算法。
需要的参数有:二维数组board;当前位置i、j;访问标记数组visited;单词遍历指针start
递归结束条件:i/j指针越界;当前元素已被访问过(visited);当前元素与单词元素不一致。
若start遍历至最后一个单词元素,表示能在board中找到访问路径。
注意 : 遍历至board[i][j]时,对应visited[i][j]应设置为true;当前路径不通时,需要回溯,记得visited[i][j]重新设为false.
public boolean exist(char[][] board, String word) {
if (board == null || board.length == 0 || board[0].length == 0)
return false;
char[] chars = word.toCharArray();
boolean[][] visited = new boolean[board.length][board[0].length];
for (int i=0;i<board.length;i++){
for (int j=0;j<board[0].length;j++){
if (dfs(board,chars,visited,i,j,0)){
return true;
}
}
}
return false;
}
private boolean dfs(char[][] board,char[] chars,boolean[][] visited,int i,int j,int start){
if (i<0 || i>=board.length || j<0 || j>=board[0].length || chars[start]!=board[i][j] || visited[i][j]){
return false;
}
if (start == chars.length-1)
return true;
visited[i][j] = true;
boolean ans = false;
ans = dfs(board,chars,visited,i-1,j,start+1) ||
dfs(board,chars,visited,i+1,j,start+1) ||
dfs(board,chars,visited,i,j-1,start+1) ||
dfs(board,chars,visited,i,j+1,start+1);
visited[i][j] = false;
return ans;
}
思路:(错误的)刚开始想的是双重循环,分别算出横纵坐标的十位、个位数字,相加<=k则count+1。这种解法未考虑路上有故障的情况,比如 m=n=12,k=1。理论上[10,0]或者[0,10]是可以访问的,但[9,0]/[0,9]不能访问,因此不能通过[9,0]到达[10,0]。
考虑到上述情况,仍使用dfs+回溯。跟上题很像,递归结束条件是:i/j越界;当前元素已被访问过;各位元素之和>k。若当前元素满足条件,则搜索附近格子,注意此时count+1。
public int movingCount(int m, int n, int k) {
boolean[][] visited = new boolean[m][n];
return dfs(0,0,m,n,k,visited);
}
private int dfs(int i,int j,int m,int n,int k,boolean visited[][]){
if (i<0 || i>=m || j<0 || j>=n || (i/10+i%10+j/10+j%10)>k || visited[i][j]){
return 0;
}
visited[i][j] = true;
return dfs(i-1,j,m,n,k,visited)+dfs(i+1,j,m,n,k,visited)+
dfs(i,j-1,m,n,k,visited)+dfs(i,j+1,m,n,k,visited)+1;
}