LeetCode 面试经典 150_回溯_单词搜索(104_79_C++_中等)

LeetCode 面试经典 150_回溯_单词搜索(104_79_C++_中等)

题目描述:

给定一个 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

示例 3:

输入 :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 仅由大小写英文字母组成

题解:

解题思路:

思路一(深度优先搜索(回溯)):

1、根据搜索的过程,可以容易的推出使用深度优先 的方法进行搜素。

具体思路如下:

对图中的每个结点进行一次深度优先搜索 ,若存在匹配则返回true,不存在匹配则返回 false。

② 在进行深度优先遍历的时候先判断表格中字母与word中第一个字母是否相同,若相同则进行深度优先搜索,每次搜索依次与word中的下一个字母进行比较。

若每次比较字母相同则将此字母标记为已搜索 ,继续进行搜索,搜索到所有 word 中的字母则返回 true 。
另一种代码实现形式可参考此文章:LeetCode 热题 100_单词搜索(60_79_中等_C++)(深度优先搜索(回溯))(初始化二维vector的大小)

2、复杂度分析:

① 时间复杂度:一个非常宽松的上界为 O(MN3L ),M,N 为网格的长度与宽度。L 为字符串 word 的长度。在图上每个点进行一个深度搜先搜索,总共有 MN 个点。搜索失败,最深的搜索的深度为(L-1),每个点有上下左右四个搜索方向,方式搜索过的点不进行搜索,所以为 3L。所以总的时间复杂度为 O(MN 3L )。

② 空间复杂度:

代码实现

代码实现(思路一(深度优先搜索(回溯))):
cpp 复制代码
class Solution {
    bool backtracking(vector<vector<char>>& board, string& word, int row, int col, int i) {
        if (i == word.size()) {
            return true; // 找到完整单词
        }

        // 边界条件和字符匹配
        if (row < 0 || row >= board.size() || col < 0 || col >= board[0].size() || board[row][col] != word[i]) {
            return false; // 超出边界或字符不匹配
        }

        // 标记当前单元格为已访问
        char temp = board[row][col];
        board[row][col] = '#'; // 使用特殊字符标记为已访问
        
        // 进行四个方向的递归搜索
        bool found = backtracking(board, word, row - 1, col, i + 1) || // 上
                     backtracking(board, word, row + 1, col, i + 1) || // 下
                     backtracking(board, word, row, col - 1, i + 1) || // 左
                     backtracking(board, word, row, col + 1, i + 1);   // 右

        // 回溯
        board[row][col] = temp; // 恢复状态
        return found; // 返回结果
    }
    
public:
    bool exist(vector<vector<char>>& board, string word) {
        for (int i = 0; i < board.size(); ++i) {
            for (int j = 0; j < board[0].size(); ++j) {
                if (backtracking(board, word, i, j, 0)) {
                    return true; // 找到单词
                }
            }
        }
        return false; // 未找到单词
    }
};
以思路一为例进行调试
cpp 复制代码
#include<iostream>
#include <vector>
using namespace std;

class Solution {
    bool backtracking(vector<vector<char>>& board, string& word, int row, int col, int i) {
        if (i == word.size()) {
            return true; // 找到完整单词
        }

        // 边界条件和字符匹配
        if (row < 0 || row >= board.size() || col < 0 || col >= board[0].size() || board[row][col] != word[i]) {
            return false; // 超出边界或字符不匹配
        }

        // 标记当前单元格为已访问
        char temp = board[row][col];
        board[row][col] = '#'; // 使用特殊字符标记为已访问
        
        // 进行四个方向的递归搜索
        bool found = backtracking(board, word, row - 1, col, i + 1) || // 上
                     backtracking(board, word, row + 1, col, i + 1) || // 下
                     backtracking(board, word, row, col - 1, i + 1) || // 左
                     backtracking(board, word, row, col + 1, i + 1);   // 右

        // 回溯
        board[row][col] = temp; // 恢复状态
        return found; // 返回结果
    }
    
public:
    bool exist(vector<vector<char>>& board, string word) {
        for (int i = 0; i < board.size(); ++i) {
            for (int j = 0; j < board[0].size(); ++j) {
                if (backtracking(board, word, i, j, 0)) {
                    return true; // 找到单词
                }
            }
        }
        return false; // 未找到单词
    }
};


int main(int argc, char const *argv[])
{
    // 初始化网格
    vector<vector<char>> board = {{'A','B','C','E'},{'S','F','C','S'},{'A','D','E','E'}};
    // 初始化要查找的单词 'word'
    string word = "ABCCED";

    // 创建 Solution 类的对象 's',用于调用 'exist' 函数
    // 如果找到了,输出 "true"
    Solution s;
    if (s.exist(board,word))
    {
        cout<<"true";
    }else{
        cout<<"false";
    }
    
    return 0;
}

LeetCode 面试经典 150_回溯_单词搜索(104_79)原题链接

欢迎大家和我沟通交流(✿◠‿◠)

相关推荐
阿蒙Amon2 小时前
C#每日面试题-进程和线程的区别
java·面试·c#
superman超哥2 小时前
仓颉语言智能指针深度实战:突破 GC 与所有权的边界
c语言·开发语言·c++·python·仓颉
八月的雨季 最後的冰吻2 小时前
FFmepg-- 39-ffplay源码-ffplay 播放器中视频输出和尺寸变换
c++·音视频
YJlio2 小时前
Sysinternals 文件工具学习笔记(12.12):常见踩坑场景、排障套路与面试问题
笔记·学习·面试
AuroraWanderll2 小时前
类和对象(四):默认成员函数详解与运算符重载(下)
c语言·数据结构·c++·算法·stl
2401_841495642 小时前
【LeetCode刷题】杨辉三角
数据结构·python·算法·leetcode·杨辉三角·时间复杂度·空间复杂度
Cinema KI2 小时前
二叉搜索树的那些事儿
数据结构·c++
LYFlied3 小时前
【每日算法】LeetCode 62. 不同路径(多维动态规划)
前端·数据结构·算法·leetcode·动态规划
Trouvaille ~3 小时前
【C++篇】C++11新特性详解(一):基础特性与类的增强
c++·stl·c++11·类和对象·语法·默认成员函数·初始化列表