数据结构学习 12字母迷宫

dfs 回溯 剪枝

这个题和dfs有关,但是我之前没有接触过,我看了这一篇很好的文章,看完之后写的答案。

我觉得很好的总结:

dfs模板


int check(参数)
{
    if(满足条件)
        return 1;
    return 0;
}
 
void dfs(int step)
{
        判断边界
        {
            相应操作
        }
        尝试每一种可能
        {
               满足check条件
               标记
               继续下一步dfs(step+1)
               恢复初始状态(回溯的时候要用到)
        }
} 

尝试每一种可能,一般都是用for循环。

在一些情况下,for循环这一步可以写到外面去,然后再调用dfs,比如这题就可以。 


题目:


我的思路:

其实就是模仿我刚刚提到的文章。

 我的dfs是:bool dfs(std::vector<std::vector<char>>& grid, std::string target, int step, int pre_i, int pre_j)

是拿上一步的pre_i和pre_j作为输入,然后我发现这样写没办法启动dfs,但是我当时脑子抽了,没找到直接输入i和j就能做出来的办法。所以只能第一步遍历所有格子的时候,把它写在dfs外面,总之有点愚蠢。但是,执行时间和内存都比我下一种写法要少很多,这是为啥?

(我自己写的)

复杂度:

代码:

#include <vector>
#include <string>
#include <iostream>
//我写的 dfs 剪枝 回溯
class Solution {
public:
    Solution(){}
    bool wordPuzzle(std::vector<std::vector<char>>& grid, std::string target) {
        n = target.size();
        if (n == 0 || grid.empty() || grid[0].empty())return false;
        rows = grid.size();//行
        cols = grid[0].size();//列
        int step = 1;
        vis = std::vector<int>(rows * cols);
        res = std::vector<char>(n);
        for (int i = 0; i < rows; ++i)//因为我写的dfs需要接受前一个dfs的位置i,j,为了启动,只能把第一轮遍历写在外面了
        {
            for (int j = 0; j < cols; ++j)
            {
                if (grid[i][j] == target[step - 1])
                {
                    res[step - 1] = grid[i][j];//访问
                    vis[i * cols + j] = 1;//标记
                    result = dfs(grid, target, step + 1, i, j);
                    if (result)return result;
                    vis[i * cols + j] = 0;//回溯
                    res[step - 1] = '\0';//回溯
                }
            }
        }
        return result;
    }
private:
    bool dfs(std::vector<std::vector<char>>& grid, std::string target, int step, int pre_i, int pre_j)
    {
        if (step == n + 1)return true;//中止条件 判断边界
        for (int i = 0; i < rows; ++i)//尝试每一种可能
        {
            for (int j = 0; j < cols; ++j)
            {
                if (vis[i * cols + j] == 0 &&//走过的不要
                    grid[i][j] == target[step-1]&&//不相同的直接不要
                    ((i * cols + j) == (pre_i * cols + pre_j - cols) ||//上
                        (i * cols + j) == (pre_i * cols + pre_j + cols) ||//下
                        (i == pre_i && j == pre_j - 1) ||//左
                        (i == pre_i && j == pre_j + 1)))//右
                {
                    res[step-1] = grid[i][j];//访问
                    vis[i * cols + j] = 1;//标记
                    result = dfs(grid, target, step + 1, i, j);//下一个
                    if (result)return result;
                    vis[i * cols + j] = 0;//回溯
                    res[step - 1] = '\0';//回溯
                }
            }
        }
        return result;
    }
    int n = 0;
    int rows = 0;
    int cols = 0;
    std::vector<int> vis;
    std::vector<char> res;
    bool result = false;
};

void Test_solution1()
{
    Solution solution;
    std::vector<std::vector<char>> grid{ { 'C','A','A'} ,{'A','A','A'},{'B','C','D'} };
    std::cout<< solution.wordPuzzle(grid ,std::string("AAB"));

}

答案思路:

 把循环写到dfs外面了。

dfs判断的是当前的点。所以dfs是:

dfs(std::vector<std::vector<char>>& grid, std::string target, int step, int i, int j),

这里传进来的i和j是需要被判断的点,而不是我写的pre_i和pre_j

找方向用的是:

            result = dfs(grid, target, step + 1, i - 1, j) ||
                dfs(grid, target, step + 1, i + 1, j) ||
                dfs(grid, target, step + 1, i, j - 1) ||
                dfs(grid, target, step + 1, i, j + 1);

比我的好多了,呵呵。

但是测试的时间和内存异常多。然后我又测试了答案提供的,还是很多时间和内存,很奇怪啊。

 

看了答案之后自己根据思路重新写了一遍代码:

#include <vector>
#include <string>
#include <iostream>
//看了答案之后模仿写的 dfs 剪枝 回溯
//这个要用很多内存 呃,为什么?
class Solution {
public:
    Solution() {}
    bool wordPuzzle(std::vector<std::vector<char>>& grid, std::string target) {
        n = target.size();
        if (n == 0 || grid.empty() || grid[0].empty())return false;
        rows = grid.size();//行
        cols = grid[0].size();//列
        int step = 1;
        vis = std::vector<int>(rows * cols);
        //res = std::vector<char>(n);
        for (int i = 0; i < rows; ++i)//循环写在外面了
        {
            for (int j = 0; j < cols; ++j)
            {
                result = dfs(grid, target, step, i, j);
                if (result)return result;
            }
        }
        return result;
    }
private:
    bool dfs(std::vector<std::vector<char>>& grid, std::string target, int step, int i, int j)
    {
        if (step == n + 1)return true;//中止条件
        if (i >= 0 && i < rows && j >= 0 && j < cols &&//超过的不要
            vis[i * cols + j] == 0 &&//走过的不要
            grid[i][j] == target[step - 1])//不相同的直接不要
        {
            //res[step - 1] = grid[i][j];//访问
            vis[i * cols + j] = 1;//标记
            result = dfs(grid, target, step + 1, i - 1, j) ||
                dfs(grid, target, step + 1, i + 1, j) ||
                dfs(grid, target, step + 1, i, j - 1) ||
                dfs(grid, target, step + 1, i, j + 1);
            if (result)return result;
            vis[i * cols + j] = 0;
            //res[step - 1] = '\0';
        }
        return result;
    }
    int n = 0;
    int rows = 0;
    int cols = 0;
    std::vector<int> vis;
    //std::vector<char> res;
    bool result = false;
};

void Test_solution2()
{
    Solution solution;
    std::vector<std::vector<char>> grid{ { 'C','A','A'} ,{'A','A','A'},{'B','C','D'} };
    std::cout << solution.wordPuzzle(grid, std::string("AAB"));

}

测试结果:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/245044.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自考 00023高等数学考点整理

空间直角坐标系 右手法则 向量 点到点的距离 点到直线的距离点到平面的距离向量平行向量垂直向量投影向量数乘 a*b axb(行列式计算)直线夹角、直线与平面夹角平面点法式方程空间直角坐标系 右手法则向量数量积、向量积 平行四边形法则、三角形法则 第二章 多元函数 微分学…

VS2022 将项目打包,导出为exe运行

我有一个在 VS2022 上开发的程序&#xff0c;基于.net 6框架, 想打包成 .exe程序&#xff0c;以在另一个没有安装VS的机器上运行&#xff0c;另一个机器是Win7系统&#xff0c;上面安装了.net 6框架。 虽然网上很多教程&#xff0c;需要安装Project Installer&#xff0c;配置A…

从零开始创建一个项目,springBoot+mybatisPlus+mysql+swagger+maven

一&#xff0c;前提 从零开始创建一个项目&#xff0c;绑定了数据库 用到的技术栈&#xff1a;springBootmybatisPlusmysqlswaggermaven 二&#xff0c;创建项目步骤 1&#xff0c;创建项目 创建出来的项目结构如图所示 2&#xff0c;修改配置文件 因为我比较习惯yml语言&…

算法:最小生成树

文章目录 生成树Kruskal算法Prim算法 本篇总结的是最小生成树算法 生成树 连通图中的每一棵生成树&#xff0c;都是原图的一个极大无环子图&#xff0c;即&#xff1a;从其中删去任何一条边&#xff0c;生成树就不在连通&#xff1b;反之&#xff0c;在其中引入任何一条新边&…

路由器交换机配置备份工具

本文主要介绍fast-backup 2.0软件的使用&#xff0c;fast-backup 2.0是可以在任何Windows系统上运行的网络运维软件&#xff0c;帮助运维人员减少大量重复的交换机等设备的配置下载工作&#xff0c;支持的厂商有华为和华三的网络设备和安全设备。 功能特性&#xff1a; 支持S…

提升数据分析效率:Amazon S3 Express One Zone数据湖实战教程

前言 什么是 Amazon S3&#xff1f;什么是 S3 Express One Zone&#xff1f;实现概述 技术架构组件实现步骤概览 第一步&#xff1a;构建数据湖的基础第二步&#xff1a;选择并查看数据集第三步&#xff1a;在 Athena 中搭建架构第四步&#xff1a;数据转换与优化第五步&#x…

数组笔试题解析(下)

数组面试题解析 字符数组 &#xff08;一&#xff09; 我们上一篇文章学习了一维数组的面试题解析内容和字符数组的部分内容&#xff0c;我们这篇文章讲解一下字符数组和指针剩余面试题的解析内容&#xff0c;那现在&#xff0c;我们开始吧。 我们继续看一组字符数组的面试…

binkw32.dll丢失怎么办?这5个方法都可以解决binkw32.dll丢失问题

binkw32.dll文件是什么&#xff1f; binkw32.dll是一个动态链接库文件&#xff0c;它是Windows操作系统中的一个重要组件。它包含了许多用于处理多媒体文件的函数和资源&#xff0c;如视频、音频等。当我们在电脑上打开或播放某些多媒体文件时&#xff0c;系统会调用binkw32.d…

【算法】滑动窗口

目录 基本思想 应用场景 应用实例 总结 基本思想 滑动窗口&#xff0c;也叫尺取法&#xff0c;就是不断的调节子序列的起始位置和终止位置&#xff0c;从而得出我们要想的结果&#xff0c;可以用来解决一些查找满足一定条件的连续区间的性质&#xff08;长度等&#xff09;…

【活动回顾】Databend 云数仓与 Databend Playground 扩展组件介绍

2023 年 12 月 7 日&#xff0c;作为 KubeSphere 的合作伙伴&#xff0c;Databend 荣幸地受邀参与了 KubeSphere 社区主办的云原生技术直播活动。本次活动的核心议题为「Databend 云数仓与 Databend Playground 扩展组件介绍」&#xff0c;此次分享由 Databend Labs 的研发工程…

Vue3-08-条件渲染-v-if 的基本使用

v-if 是什么 v-if 一个指令&#xff0c; 它是用来根据条件表达式&#xff0c;进行选择性地【展示】/【不展示】html元素的。比如 &#xff1a; 有一个按钮A&#xff0c;当条件为真时&#xff0c;展示该按钮&#xff1b;条件为假时&#xff0c;不展示该按钮。与 js 中的 条件判…

如何部署Portainer容器管理工具+cpolar内网穿透实现公网访问管理界面

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 本文主要介绍如何本地安装Portainer并结合内网穿透工具实现任意浏览器远程访问管理界面。Portainer 是一个轻量级…

一文5000字从0到1构建高效的接口自动化测试框架思路

在选择接口测试自动化框架时&#xff0c;需要根据团队的技术栈和项目需求来综合考虑。对于测试团队来说&#xff0c;使用Python相关的测试框架更为便捷。无论选择哪种框架&#xff0c;重要的是确保 框架功能完备&#xff0c;易于维护和扩展&#xff0c;提高测试效率和准确性。…

挺进云存储,天翼云全新一代XSSD勇立潮头

引言&#xff1a;自研高性能分布式存储引擎LAVA&#xff0c;实现云硬盘持续创新获得新突。 【全球云观察 &#xff5c; 科技热点关注】 作为算力基础设施的基石&#xff0c;云存储的发展一直备受公有云厂商所重视&#xff0c;对拉动云厂商营收规模带来重要价值&#xff0c;就…

山海鲸开发者:展现数据可视化在各领域的无限可能

作为一名山海鲸可视化软件的内部开发者&#xff0c;我对这款软件投入了大量的经历以及含有深深的情感。下面&#xff0c;我从这款软件应用场景下手&#xff0c;带大家探秘这款软件的多种可能性以及我们的用心。 首先&#xff0c;从行业角度来看&#xff0c;山海鲸可视化软件可以…

06.迪米特法则(Demeter Principle)

明 嘉靖四十年 江南织造总局 小黄门唯唯诺诺的听完了镇守太监杨金水的训斥&#xff0c;赶忙回答&#xff1a;“知道了&#xff0c;干爹&#xff01;” “知道什么&#xff1f;&#xff01;&#xff01;” 杨金水打断了他的话&#xff0c;眼神突然变得凌厉起来&#xff1a; “有…

椋鸟C语言笔记#26:数据在内存中的存储(大小端字节序)、浮点数的存储(IEEE754)

萌新的学习笔记&#xff0c;写错了恳请斧正。 目录 大小端字节序 什么是大小端 写一个判断大小端的程序 浮点数在内存中的存储&#xff08;IEEE 754规则&#xff09; 引入 存储规则解释 读取规则解释 1.阶码不全为0或全为1&#xff08;规格化数&#xff09; 2.阶码全为…

鸿蒙系统走向独立,高校设立“鸿蒙班”,鸿蒙人才紧缺!

近日&#xff0c;华为以及鸿蒙系软件厂商都在积极培养鸿蒙开发人才&#xff0c;产学联动、产教融合是重要的一条路径。目前已有23家985高校、46家211高校已开设或即将开设HarmonyOS相关课程。 一位鸿蒙生态内部人士表示&#xff0c;目前鸿蒙开发人才比较紧缺&#xff0c;而安卓…

图生视频AI技术,1张图零提示词,让静态照片动起来

AI时代的发展速度比我们想象中的快多了&#xff0c;当大部分人刚学会AI生成图片时&#xff0c;现在又开始流行AI生成视频了&#xff0c;正式从图片、文字升级到短视频时代。 最近一段时间&#xff0c;AI生成视频的技术正在突飞猛进。Pika、Runway等大家熟知的海外工具都在不断…

【STM32CubeMX】F103 BxCAN

F103&BxCAN bxCAN总体描述 有一个增强的过滤机制来处理各种类型的报文此外&#xff0c;应用层任务需要更多CPU时间&#xff0c;因此报文接收所需的实时响应程度需要减轻。 接收FIFO的方案允许&#xff0c;CPU花很长时间处理应用层任务而不会丢失报文。 构筑在底层CAN驱动程…