IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 深度优先搜索(一)--- 矩阵中的路径 -> 正文阅读

[数据结构与算法]深度优先搜索(一)--- 矩阵中的路径

什么是深度优先搜索?

???深度优先搜索(DFS)属于图算法的一种,类似于树的前序遍历,是树的前序遍历的推广。过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。

??关于树的前序遍历可以参考上一篇博文:二叉树的遍历

深度优先搜索的过程

  1. 从图中某个顶点v出发,访问顶点v
  2. 找出刚访问过的顶点的第一个未被访问的邻接点,访问该顶点。以该顶点为新顶点,重复此步骤,直至刚访问过的顶点没有未被访问的邻接点为止。
  3. 返回前一个访问过的且仍有未被访问的邻接点的顶点,找出该顶点的下一个未被访问的邻接点,访问该顶点。
  4. 重复此步骤(2)和(3),直至图中所有顶点均被访问过,访问结束。

??用图表示一下:(蓝色实线表示访问下一个未被访问邻接点,红色虚线表示回溯,路线旁的数字表示访问的顺序)
在这里插入图片描述

??所以搜索结果为: v1 v2 v4 v8 v5 v3 v6 v7 (深度优先搜索的结果不是唯一的,因为每个邻接点大于1的节点在访问该节点的邻接点时的顺序不唯一)

深度优先搜索题目:

力扣 剑指offer12.矩阵中的路径

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

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

例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。

img

示例 1:

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

示例 2:

输入:board = [["a","b"],["c","d"]], word = "abcd"
输出:false

? 这道题使用深度优先搜索,先朝一个方向搜到底,在回溯至上一个节点,选择另一条满足条件的路线,直至找出结果。

递归参数: 当前元素在board中的索引值 i 和 j ,当前目标字符在 word 中的索引 k。

终止条件:

? 1.返回false:行或列索引越界 或 当前矩阵元素与目标字符不同 或当前矩阵元素已经访问过。

? 2.返回true:k = word.length - 1, 表示字符串word全部匹配

递推工作:

? 1.声明一个和board数组同样空间大小的辅助数组,全部赋值为false,代表全部未被访问,用来判断当前矩阵元素是否被访问过,访问的时候改为true,当前层dfs结束回溯时改回false,防止不能回溯。

? 2.搜索下一单元格:朝当前元素的上或 右 或 下 或 左四个方向开始下层dfs,循环步骤 1。

返回值: 返回布尔值ans,代表是否搜索到目标字符串word

代码实现:

var exist = function(board, word) {
    let ans = false//结果初始化为false(如果遍历完整个矩阵都没有结果则返回该值)
    const row = board.length//board的行
    const col = board[0].length//board的列
    const end = word.length-1//目标字符串的长度
    //用来判断矩阵当前字符是否走过,开始时false表示每个格子都没有被访问过
    const visited = new Array(row).fill(0).map(() => new Array(col).fill(false))
    const ways = [[-1,0], [0,1], [1,0], [0,-1]]//向上右下左的路线
	
    //判断i,j是否越界
    const overBoarder = (i, j) => {
        return i < 0 || i >= row || j<0 || j >= col
    }

    //深度优先搜索(递归循环)
    const dfs = (i, j, k) => {
        //1.确定是否找到答案(是否满足条件)
        if(k > end || ans){
            return
        }
        //2.是否终止
        if(k === end){
            return ans = true
        }
        
        //3.继续搜索
        for(const way of ways){
            //往哪走
            let [si, sj] = way
            const ni = i+si
            const nj = j+sj
            //判断当前所选择的字符是否越界,越界则跳过下边语句结束本次循环,选择另一条way
            if(overBoarder(ni, nj)){
                continue
            }
            //判断当前所选择的字符是否等于下一个目标字符串,不等于则结束本次循环,另选其他路径
            if(board[ni][nj] !== word[k+1]){
                continue
            }
            //判断当前所选择的字符是否被访问过,访问过则结束本次循环,另选其他路径
            if(visited[ni][nj] == true){
                continue
            }
            //此时所选择的字符符合所有条件,访问该字符,并把该字符在visited中的位置改为true
            visited[ni][nj] = true
            //从当前所选择的字符进行搜索,直至最后
            dfs(ni, nj, k+1)
            //这一步是当前层dfs结束时把对应的visited改回false,因为在回溯两次的时候,第一次回溯的那个值可能以后还会用到,如果为true,则影响回溯
            visited[ni][nj] = false
        }
    }
    outer: for(let i = 0; i < row ; i++){
            for(let j = 0; j < col ; j++){
                if(ans){
                    break outer;//outer是在跳出本层循环的时候也跳出外层循环,因为此时外层循环也没有再循环的必要了,目的是防止算法超出时间限制
                }
                if(board[i][j] == word[0]){
                    visited[i][j] = true //表示这个字符被访问过了
                    dfs(i, j, 0)
                    visited[i][j] = false//重置为false,
                }
            }
    }
    return ans
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-29 12:21:18  更:2022-04-29 12:25:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:31:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码