LeetCode79. 单词搜索

该博客介绍了如何利用深度优先搜索(DFS)和回溯策略解决在一个给定的二维字符网格中查找给定单词的问题。题目要求按照字母顺序,通过相邻单元格查找单词,不允许重复使用同一单元格。提供的代码示例展示了如何实现这个算法,包括搜索过程中的标记、回溯以及边界条件的判断。时间复杂度为O(M·N·3L),空间复杂度为O(1)。
摘要由CSDN通过智能技术生成

description

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例 1:
在这里插入图片描述

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true

示例2:
在这里插入图片描述

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “SEE”
输出:true

在这里插入图片描述

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCB”
输出:false

提示:
m == board.length
n = board[i].length
1 <= m, n <= 6
1 <= word.length <= 15
board 和 word 仅由大小写英文字母组成

分析:

一道深度优先搜索+回溯的题,回溯是dfs的一种,在搜索过程中,要将已搜索过的格子进行标记,同时考虑回溯,在选择了当前格子进行递归后要进行"归还"。

解法:回溯

在字符网格中枚举每个字符作为起点,从该起点开始向四周搜索,与word字符串进行匹配,重点:要记录当前枚举到word中的位置idx(从0开始)。
如果当前搜索的位置(x,y)的元素与word中当前枚举到的元素相同,则继续向四周进行搜索,否则返回false。

枚举到word的最后一个字母,判断为匹配时,返回true,否则返回false。
回溯前,要保存网格中当前访问的元素,并将访问过的点置为特殊标记(这里使用’.’),回溯后要将该格子的元素复原(使用前面保存过的元素)。
递归结束条件:

  1. board[x][y] != word[u],说明当前路径无法匹配,返回false
  2. idx == word.size() - 1,说明已经走到word的最后一个字符,在此句之前进行判断,已经匹配,即全部匹配,所以返回true。

网格中遍历的条件判断:
横纵坐标<0 或 横纵坐标 > 网格长宽 或 当前访问点已被置为’ . '(已访问过)。

代码实现

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        for(int i = 0; i < board.size(); i++){
            for(int j = 0; j < board[i].size(); j++){
                if(dfs(board, word, 0, i, j))
                    return true;
            }
        }
        return false;
    }
    int dx[4] = {-1,0,1,0}, dy[4] = {0,1,0,-1};
    bool dfs(vector<vector<char>>& board, string& word, int idx, int x, int y){
        if(board[x][y] != word[idx]) return false;
        //idx从0开始 如果上一步未返回true说明最后一个字符匹配,返回true结束
        if(idx == word.size() - 1) return true;
        char t = board[x][y];

        board[x][y] = '.';
        for(int i = 0; i < 4; i++){
            int a = x + dx[i], b = y + dy[i];
            // 已出界 / 走到已搜索过的位置
            if(a < 0 || b < 0 || a >= board.size() || b >= board[0].size() || board[a][b] == '.')
                continue;
            if(dfs(board, word, idx + 1, a, b))
                return true;
        }
        board[x][y] = t;
        return false;
    }
};
int dx[4] = {-1,0,1,0}, dy[4] = {0,1,0,-1};

此处使用了上述定义方式来实现对当前格子的四个方向搜索。

复杂度:

  • 时间复杂度:O(M·N·3L) L为字符串word长度,M、N为网格长宽。

  • 空间复杂度:O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值