版权声明:版权所有,转载请注明原网址链接。 https://blog.csdn.net/qq_41231926/article/details/81623607
原题链接:https://leetcode-cn.com/problems/word-search/description/
题目描述:
知识点:递归,回溯
基本思路:
这是一个二维平面上的回溯法的应用的经典例题。
我们在board数组里首先定位到word字符串的第0个元素所在的二维坐标(i, j)的值,然后从该(i, j)点按照上右下左4个方向的顺序取寻找下一个字符,如果找到,将该位置标记为已经被访问过,就继续递归地调用该函数继续寻找下一个字符,如果该函数返回的是true,表示能寻找到下一个字符,我们直接返回true。否则,我们需要退回到上一步,即取消对该位置已经访问过这一标记(变量的手动回溯!!!)。
如果4个方向都没有找到下一个字符,则直接返回false。
JAVA代码:
public boolean exist(char[][] board, String word) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
if(board[i][j] == word.charAt(0)) {
boolean[][] visited = new boolean[board.length][board[0].length];
visited[i][j] = true;
if(isConnected(board, i, j, 1, word, visited)) {
return true;
}
}
}
}
return false;
}
/*
* word的第n个字符与之前的字符已经,寻找word的第n个字符的上右下左中是否有word的第n + 1个字符
* 第n个字符所在board数组中的坐标为(i, j)
*/
private boolean isConnected(char[][] board, int i, int j, int n, String word, boolean[][] visited) {
System.out.println("(" + i + ", " + j + ")");
if(n == word.length()) {
return true;
}
if(i - 1 >= 0 && board[i - 1][j] == word.charAt(n) && !visited[i - 1][j]) {
visited[i - 1][j] = true;
if(isConnected(board, i - 1, j, n + 1, word, visited)) {
return true;
}
visited[i - 1][j] = false;
}
if(j + 1 < board[i].length && board[i][j + 1] == word.charAt(n) && !visited[i][j + 1]) {
visited[i][j + 1] = true;
if(isConnected(board, i, j + 1, n + 1, word, visited)) {
return true;
}
visited[i][j + 1] = false;
}
if(i + 1 < board.length && board[i + 1][j] == word.charAt(n) && !visited[i + 1][j]) {
visited[i + 1][j] = true;
if(isConnected(board, i + 1, j, n + 1, word, visited)) {
return true;
}
visited[i + 1][j] = false;
}
if(j - 1 >= 0 && board[i][j - 1] == word.charAt(n) && !visited[i][j - 1]) {
visited[i][j - 1] = true;
if(isConnected(board, i, j - 1, n + 1, word, visited)) {
return true;
}
visited[i][j - 1] = false;
}
return false;
}
复杂度分析:
时间复杂度:需要递归O(len(word))层,每层所做的操作都是O(1)的复杂度,故时间复杂度为O(len(word))。
空间复杂度:需要递归len(word)层,故空间复杂度为O(len(word))。