[leetbook中级算法-回溯算法(java解法)]LC单词搜索

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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值