[leetbook中級演算法-回溯演算法(java解法)]LC單詞搜尋
阿新 • • 發佈:2021-01-26
技術標籤:演算法練習leetbook剪枝leetcode字串dfs回溯
leetbook:中級演算法
型別:回溯演算法
題目名:單詞搜尋
原題URL:https://leetcode-cn.com/leetbook/read/top-interview-questions-medium/xvkwe2/
題目描述
給定一個二維網格和一個單詞,找出該單詞是否存在於網格中。
單詞必須按照字母順序,通過相鄰的單元格內的字母構成,其中“相鄰”單元格是那些水平相鄰或垂直相鄰的單元格。同一個單元格內的字母不允許被重複使用。
示例
示例 1:
board = [ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ] 給定 word = "ABCCED", 返回 true 給定 word = "SEE", 返回 true 給定 word = "ABCB", 返回 false
限制
- board 和 word 中只包含大寫和小寫英文字母。
- 1 <= board.length <= 200
- 1 <= board[i].length <= 200
- 1 <= word.length <= 10^3
解題思路
1.遍歷整個單詞二維陣列,對每個字元開始進行上下左右的dfs搜尋,如果找到就返回true
2.具體dfs是一個回溯剪枝的dfs過程
3.如果字串長度等於目標字串的長度,說明已經找到了,退出dfs
4.如果越界,或者遍歷到的當前字元和需要的目標字串的字元不相等,直接返回
5.如果這個字串已經被遍歷到了,那麼在這次遍歷中將它標記為不會出現的字元’1’,以防他遍歷到下面的時候又遍歷回來
6.3,4,5是剪枝條件,現在上下左右進行遍歷,如果找到一個地方可以返回目標字串直接返回true
7.如果當前位置的上下左右都不能繼續遍歷,那麼直接進行回溯
解題程式碼
class Solution {
public boolean exist(char[][] board, String word) {
char[] chars = word.toCharArray();
StringBuilder sb = new StringBuilder();
for(int i=0;i<board.length;i++) {
for (int j=0;j<board[0].length;j++) {
if(dfs(sb,board,i,j,chars,0)) return true;
}
}
return false;
}
public boolean dfs(StringBuilder sb,char[][] board, int i,int j,char[] chars,int idx) {
if(sb.length()==chars.length) {
return true;
}
//越界條件,直接返回
if(!inArea(board,i,j)||idx>chars.length-1||board[i][j]!=chars[idx]) return false;
sb.append(board[i][j]);
char temp = board[i][j];
board[i][j] = '1';
boolean isUsed = dfs(sb,board,i-1,j,chars,idx+1)||
dfs(sb,board,i+1,j,chars,idx+1)||
dfs(sb,board,i,j-1,chars,idx+1)||
dfs(sb,board,i,j+1,chars,idx+1);
if(!isUsed) {
sb.deleteCharAt(sb.length()-1);
board[i][j]=temp;
return false;
}else return true;
}
public boolean inArea(char[][] board, int row,int col) {
return row>=0&&col>=0&&row<board.length&&col<board[0].length;
}
}