【LeetCode】Day132-单词搜索

本文详细介绍了如何利用回溯搜索解决二维网格中查找特定单词的问题。核心在于`backtrack`函数,它判断以指定位置出发能否找到单词。每个位置最多进入3个分支,时间复杂度为O(mn*3^l),空间复杂度为O(mn)。文章强调了避免重复遍历的重要性,并提供了偏移量数组作为常见技巧。
摘要由CSDN通过智能技术生成

题目

79. 单词搜索【中等】

题解

在经过几道回溯题之后,终于迎来了回溯搜索类型题,而且还是道二维平面上的回溯,不是简单套模板就可以ac的了

设函数check(i,j,k) 表示判断以网格的 (i,j) 位置出发,能否搜索到单词 word[k…]

  • 如果board[i][j]!=word[k],返回false
  • 如果已经访问到字符串末尾,并且对应字符依然匹配,返回true
  • 否则,遍历当前位置的所有相邻位置。如果从某个相邻位置出发,能够搜索到子串word[k+1…]则返回true,否则返回false

每一个位置都调用check(i,j,0) 进行检查,只要有一处返回true,就说明网格中能找到对应单词
为防止重复遍历相同的位置,维护一个和board等大的visited数组,用于标识每个位置是否被访问过。遍历相邻位置时,跳过已经遍历过的位置。

class Solution {
    int m,n;
    boolean[][] visited;
    public boolean exist(char[][] board, String word) {
        m=board.length;
        n=board[0].length;
        visited=new boolean[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                //对于每个位置都进行检查,有一处满足即返回true
                if(backtrack(board,word,i,j,0))
                    return true;
            }
        }
        return false;
    }
    public boolean backtrack(char[][] board,String word,int i,int j,int k){
        //有一个字符不等就返回false
        if(board[i][j]!=word.charAt(k))
            return false;
        //该字符相等,且已到单词末尾,说明全部匹配
        else if(k==word.length()-1)
            return true;
        visited[i][j]=true;
        //遍历当前位置的四个相邻位置
        int[][] direction={{0,1},{1,0},{0,-1},{-1,0}};//偏移量数组
        for(int[] dir:direction){
            int x=i+dir[0],y=j+dir[1];
            if(x>=0&&x<m&&y>=0&&y<n){
                if(!visited[x][y]&&backtrack(board,word,x,y,k+1))
                    return true;
            }
        }
        visited[i][j]=false;//回溯
        return false;
    }
}

注:偏移量数组在二维平面内是经常使用的,可以把它的设置当做一个技巧,并且在这个问题中,偏移量数组内的 4 个偏移的顺序无关紧要

时间复杂度: O ( m n ∗ 3 l ) O(mn*3^l) O(mn3l),其中l为单词word长度,在每次调用函数 check 时,除了第一次可以进入 4 个分支以外,其余时间我们最多会进入 3 个分支(因为每个位置只能使用一次,所以走过来的分支没法走回去)。检查一次的时间复杂度是 O ( 3 l ) O(3^l) O(3l),共需O(mn)次检查。

空间复杂度: O ( m n ) O(mn) O(mn),额外的visited数组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值