数据结构算法-回溯算法

引言

在原神的世界中,小森决定挑战自我,踏上了寻找风神的迷宫——风之迷宫。这个迷宫就像是一个巨大的电玩城,让小森感到困惑和无助。他站在迷宫的入口,看着眼前乱糟糟的路径,内心充满了不安和焦虑。

“派蒙,我… 我真的不知道该怎么办了。”小森向他的老朋友派蒙诉说。

派蒙看着小森愁眉苦脸的样子,笑着说:“别担心,小森,我们可以利用深度优先搜索来寻找路径。这个算法超级强大,它会帮助我们找到一条通往风神的正确道路。”

小森听后有些疑惑,他挠了挠头,瞪大了眼睛问:“深度优先搜索?那是什么?听起来好像很高级的样子。”

派蒙笑着回答:“哈哈,别担心,小森,其实它就像是你吃蛋糕一样。我们从蛋糕的顶部开始,一口一口地吃下去,直到吃到下面为止。这就是深度优先搜索!”

小森听后恍然大悟,“哦!我明白了!就像我们在森林里迷路一样,我们要一直往下走,直到找到出口为止!”

派蒙点点头,“没错,就是这个意思。”

正当他们谈话时,另一位神秘人物小坤出现了。小坤看着小森和派蒙焦虑的样子,笑着说:“你们不必担心迷宫中的路径,我可以给你们提供一种回溯算法,这种算法可以帮助你们在迷宫中寻找路径。回溯算法就像是你走迷宫一样,如果发现走不通,就会原路返回,换一条路继续前进。”

小坤的话让小森和派蒙感到非常安心。他们决定按照小坤的指引行动。在接下来的冒险中,他们分工合作,派蒙利用深度优先搜索算法不断探索迷宫中的路径,而小坤则根据回溯算法不断调整搜索方向,引导他们找到正确的路径。

在探索的过程中,小森想起自己的冒险经历,“派蒙,你说我们会不会像以前一样遇到很多困难呢?”

派蒙看着他,“哈哈,难说呢,小森。但是我们可以抱着乐观的态度去面对。就像以前一样,遇到困难我们就一起解决。”

小森握紧拳头,“好!我相信我们一定能够成功找到风神!”

每当他们遇到困难时,他们都会相互鼓励、互相扶持着继续前进。小坤的回溯算法总是能在关键时刻指引他们走向正确的方向。

通过不断地尝试和探索,他们终于在字符矩阵中找到了通往风神的路径。在这个过程中,他们不仅学会了如何利用深度优先搜索和回溯算法来解决问题,还进一步理解了风神的哲学理念。

最终,当他们站在风神的面前时,小森感慨万分。他向派蒙表示感激:“谢谢你派蒙,如果不是你一直在我身边支持和鼓励我,我可能早就放弃了。”

派蒙笑着回答:“哈哈,别客气,小森!我们是朋友嘛!而且这个冒险旅程也让我学到了很多。”

回溯算法核心思想

回溯:尝试解决问题若某个位置卡着,就回退到那个位置,继续解决计算位置并且确确走那个位置

  1. 利用深度优先搜索算法不停段的搜索问题
  2. 若问题有障碍 就回溯到上一个子问题
  3. 直到解决问题的解
  4. 在此之上必须定义搜索问题的空间 (防止重复计算)

回溯算法实现思路

如上所说(引言里) 在字符矩阵里找到包含指定的字符串的路径是否该路径

在这里插入图片描述
如图 可以看出这搜索的路径 由左上右下策略 走这么一个路径 若都走不动,则回溯并重置路径长度和标记当前字符为未访问过状态,以便其他路径可以继续尝试访问当前字符
虽然说采用递归的方式比较绕 ,但没有必要把 每一个执行的步骤都要做到非常清楚 若是这样动脑能力都没有一点学这个 有啥意思 至于我嘛大概了解 即可没必要死磕 画这个的时候,我需要彻底掌握? 当然需要,但舍近求远 毕竟后面的内容更加精彩 技术更迭 是程序员必备技能

回溯应用算法专区

// 查找字符矩阵中子字符串的路径,返回是否存在路径  
bool FindCharMatrixSubstrPath(const char* matrix, int rows, int cols, const char* str) {  
    // 初始化返回值  
    bool ret = false;  
    // 检查输入矩阵和字符串是否有效,并且行数和列数是否大于1  
    if (matrix != nullptr && rows > 1 && cols > 1 && str != nullptr) {  
        // 初始化访问数组,用于标记已访问的字符  
        bool* visited = new bool[rows * cols] {};  
        // 初始化路径长度为0  
        int Pathlen = 0;  
        // 遍历矩阵的每个字符  
        for (size_t row = 0; row < rows; row++) {  
            for (size_t col = 0; col < cols; col++) {  
                // 检查下一个字符是否在字符矩阵路径中  
                if (CheckNextCharisCharMatrixPath(matrix, rows, cols, row, col, str, Pathlen, visited)) {  
                    // 如果找到路径,则设置返回值为true  
                    ret = true;  
                    // 终止函数执行,并释放访问数组内存  
                    delete[] visited;  
                    // 跳出内层循环,继续查找是否有其他路径  
                    break;  
                }  
            }  
            if (ret){  
                // 如果找到路径,则跳出外层循环,不再继续遍历矩阵  
                break;  
            }  
        }  
    }  
    // 返回是否存在路径的结果  
    return ret;  
}  
  
// 检查下一个字符是否在字符矩阵路径中,返回是否找到路径的结果  
bool CheckNextCharisCharMatrixPath(const char* matrix, int rows, int cols, int row, int col, const char* str, int& Pathlen, bool* visited){  
    // 如果字符串已经遍历完,则返回找到路径的结果  
    if (str[Pathlen]=='\0'){  
        return true;  
    }  
    // 初始化是否找到路径的标志为false  
    bool isPath = false;;  
    // 检查当前字符的坐标是否在矩阵范围内  
    bool CheckRange = row >= 0 && row < rows && col >= 0 && col < cols;  
    // 计算当前字符在矩阵中的索引位置  
    int matrixIndex = row * cols + col;  
    // 检查当前字符是否与字符串中的字符匹配  
    bool CheckStr = matrix[matrixIndex] == str[Pathlen];  
    // 如果坐标在矩阵范围内,字符匹配且未被访问过,则进行递归调用,检查上下左右四个方向是否可以找到路径  
    if (CheckRange && CheckStr &&!visited[matrixIndex])	{  
        // 更新路径长度并标记当前字符已访问过  
        Pathlen++;  
        visited[matrixIndex] = true;  
        // 分别检查四个方向是否可以找到路径,任意一个方向可以找到路径,则设置isPath为true,否则回溯并重置路径长度和标记当前字符为未访问过状态  
        isPath = CheckNextCharisCharMatrixPath(matrix, rows, cols, row , col-1, str, Pathlen, visited) ||   
                CheckNextCharisCharMatrixPath(matrix, rows, cols, row -1, col, str, Pathlen, visited) ||   
                CheckNextCharisCharMatrixPath(matrix, rows, cols, row, col + 1, str, Pathlen, visited) ||   
                CheckNextCharisCharMatrixPath(matrix, rows, cols, row+1, col , str, Pathlen, visited);  
        if (!isPath){  
            // 如果四个方向都没有找到路径,则回溯并重置路径长度和标记当前字符为未访问过状态,以便其他路径可以继续尝试访问当前字符  
            Pathlen--;  
            visited[matrixIndex] = false;  
        }  
    }  
    // 返回是否找到路径的结果  
    return isPath;  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小森程序员

若能帮助到你,小费自愿付费

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值