1. 程式人生 > 其它 >[leetbook中級演算法-回溯演算法(java解法)]LC單詞搜尋

[leetbook中級演算法-回溯演算法(java解法)]LC單詞搜尋

技術標籤:演算法練習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; } }