图论第四天|127. 单词接龙、841. 钥匙和房间、463. 岛屿的周长

2023-09-15 17:37:14

127. 单词接龙 ★

文档讲解 :代码随想录 - 127. 单词接龙
状态:开始学习。(★:需要多次回顾并重点回顾)

思路:
单词接龙
本题需要解决两个问题:

  1. 图中的线是如何连在一起的
    题目中并没有给出点与点之间的连线,而是要我们自己去连,条件是字符只能差一个,所以判断点与点之间的关系,要自己判断是不是差一个字符,如果差一个字符,那就是有链接。
  2. 起点和终点的最短路径长度
    这里无向图求最短路,广搜最为合适,广搜只要搜到了终点,那么一定是最短的路径。

另外注意点:

  • 本题是一个无向图,需要用标记位,标记着节点是否走过,否则就会死循环!
  • 本题给出集合是数组型的,可以转成set结构,查找更快一些

本题代码:

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        // 将vector转成unordered_set,提高查询速度
        unordered_set<string> wordSet(wordList.begin(), wordList.end());
        // 如果endWord没有在wordSet出现,直接返回0
        if (wordSet.find(endWord) == wordSet.end()) return 0;
        // 记录word是否访问过
        unordered_map<string, int> visitMap; // <word, 查询到这个word路径长度>
        // 初始化队列
        queue<string> que;
        que.push(beginWord);
        // 初始化visitMap
        visitMap.insert(pair<string, int>(beginWord, 1));

        while(!que.empty()) {
            string word = que.front();
            que.pop();
            int path = visitMap[word]; // 这个word的路径长度
            for (int i = 0; i < word.size(); i++) {
                string newWord = word; // 用一个新单词替换word,因为每次置换一个字母
                for (int j = 0 ; j < 26; j++) {
                    newWord[i] = j + 'a';
                    if (newWord == endWord) return path + 1; // 找到了end,返回path+1
                    // wordSet出现了newWord,并且newWord没有被访问过
                    if (wordSet.find(newWord) != wordSet.end()
                            && visitMap.find(newWord) == visitMap.end()) {
                        // 添加访问信息
                        visitMap.insert(pair<string, int>(newWord, path + 1));
                        que.push(newWord);
                    }
                }
            }
        }
        return 0;
    }
};

841. 钥匙和房间

文档讲解 :代码随想录 - 841. 钥匙和房间
状态:开始学习。

思路:深搜三部曲

  1. 确认递归函数,参数
    // key 当前得到的可以 
    // visited 记录访问过的房间 
    void dfs(const vector<vector<int>>& rooms, int key, vector<bool>& visited) {
    
  2. 确认终止条件
    if (visited[key]) { // 本层递归是true,说明访问过,立刻返回
       return;
    }
    
  3. 处理目前搜索节点出发的路径
        for (int key : keys) { 
            if (visited[key] == false) { // 处理下一层节点,判断是否要进行递归
                visited[key] = true;
                dfs(rooms, key, visited);
            }       
        }
    

本题代码:

class Solution {
private:
    void dfs(const vector<vector<int>>& rooms, int key, vector<bool>& visited) {
        if (visited[key]) {
            return;
        }
        visited[key] = true;
        vector<int> keys = rooms[key];
        for (int key : keys) {
            // 深度优先搜索遍历
            dfs(rooms, key, visited);
        }
    }
public:
    bool canVisitAllRooms(vector<vector<int>>& rooms) {
        vector<bool> visited(rooms.size(), false);
        dfs(rooms, 0, visited);
        //检查是否都访问到了
        for (int i : visited) {
            if (i == false) return false;
        }
        return true;
    }
};

463. 岛屿的周长

文档讲解 :代码随想录 - 463. 岛屿的周长
状态:开始学习。

简单题没必要DFS或者BFS

思路:
遍历每一个空格,遇到岛屿,计算其上下左右的情况,遇到水域或者出界的情况,就可以计算边了。
岛屿周长
本题代码:

class Solution {
public:
    int direction[4][2] = {0, 1, 1, 0, -1, 0, 0, -1};
    int islandPerimeter(vector<vector<int>>& grid) {
        int result = 0;
        for (int i = 0; i < grid.size(); i++) {
            for (int j = 0; j < grid[0].size(); j++) {
                if (grid[i][j] == 1) {
                    for (int k = 0; k < 4; k++) {       // 上下左右四个方向
                        int x = i + direction[k][0];
                        int y = j + direction[k][1];    // 计算周边坐标x,y
                        if (x < 0                       // i在边界上
                                || x >= grid.size()     // i在边界上
                                || y < 0                // j在边界上
                                || y >= grid[0].size()  // j在边界上
                                || grid[x][y] == 0) {   // x,y位置是水域
                            result++;
                        }
                    }
                }
            }
        }
        return result;
    }
};
更多推荐

数据中心液冷服务器详情说明

目录前言何为液冷服务器?为什么需要液冷?1.数据中心降低PUE的需求2.政策导向3.芯片热功率已经达到风冷散热极限4.液冷比热远大于空气液冷VS风冷,区别在哪?1.液冷服务器跟风冷服务器的区别2.液冷数据中心跟风冷数据中心的区别液冷技术详情冷板式液冷1.优势2.冷板式整机示意图3.风冷服务器改造冷板式3.1技术难点3.

JavaScript 中的变量声明与赋值

3.10JavaScript中的变量声明与赋值。在计算机编程中,使用名称(或标识符)来表示值是最基本的技术之一。将名称与值绑定为我们提供了一种在程序中引用值并利用它们的方式。当涉及到绑定名称与值时,我们通常称之为将值赋给变量。术语“变量”暗示了新的值可以被赋给它,这意味着与变量关联的值在程序执行过程中可能会改变。如果一

windows ---命令详解1

一、cdD:\k8s>cd/?显示当前目录名或改变当前目录。CHDIR[/D][drive:][path]CHDIR[..]CD[/D][drive:][path]CD[..]..指定要改成父目录。1、键入CDdrive:显示指定驱动器中的当前目录。D:\k8s>cdC:C:\Users\lichf12、不带参数只键入

2023华为杯研究生数学建模竞赛选题建议+初步分析

如下为C君的2023华为杯研究生数学建模竞赛(研赛)选题建议+初步分析2023华为杯研究生数学建模竞赛(研赛)选题建议提示:DSC君认为的难度:C=E<D<F,开放度:C=D=E<F。华为专项的题目(A、B题)暂不进行选题分析,不太建议大多数同学选择,对自己专业技能有很大自信的可以选择华为专项的题目。后续团队会直接更新

scrapy框架--

Scrapy是一个用于爬取数据的Python框架。下面是Scrapy框架的基本操作步骤:安装Scrapy:首先,确保你已经安装好了Python和pip。然后,在命令行中运行以下命令安装Scrapy:pipinstallscrapy创建Scrapy项目:使用Scrapy提供的命令行工具创建一个新的Scrapy项目。在命令

Zabbix

Zabbix前言一、内网离线安装1.下载离线RPM包1.1配置国内镜像源1.2下载zabbix所需rpm包2.内网服务器安装zabbix2.1内网服务器环境准备2.2修改yum源2.3安装2.4配置数据库2.5配置zabbix_server.conf2.6配置php配置文件2.7启动服务3.配置zabbixweb界面3

Minitab Express for Mac(数据分析软件)附破解补丁 v1.5.0 支持M1

MinitabExpress是一款专为Mac用户设计的数据分析和统计软件。它提供了一套全面的工具和功能,用于分析数据、执行统计计算和生成可视化。下载:MinitabExpressforMac(数据分析软件)附破解补丁以下是MinitabExpressforMac的一些主要功能:1.数据导入和操作:MinitabExpr

Xilinx FPGA未使用管脚上下拉状态配置(ISE和Vivado环境)

文章目录ISE开发环境Vivado开发环境方式1:XDC文件约束方式2:生成选项配置ISE开发环境ISE开发环境,可在如下Bit流文件生成选项中配置。右键点击GenerateProgrammingFile,选择ProcessProperties,在弹出的窗口选择ConfigurationOptions->UnusedP

排序算法-插入排序

属性当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移直接插入排序的特性总结:1.元素集合越接近有序

redis的基础底层篇 zset的详解

一zset的作用以及结构1.1zset作用redis的zset是一个有序的集合,和普通集合set非常相似,是一个没有重复元素的字符串集合。常用作排行榜等功能,以用户id为value,关注时间或者分数作为score进行排序。1.2zset的底层结构1.zset是一个特别的数据结构,一方面它等价于Java的数据结构Map<

Layui快速入门之第十节 表单

目录一:基本用法二:输入框普通输入框输入框点缀前置和后置前缀和后缀动态点缀密码显隐内容清除自定义动态点缀点缀事件三:复选框默认风格标签风格开关风格复选框事件四:单选框普通单选框自定义标题模板单选框事件五:选择框普通选择框分组选择框搜索选择框选择框事件六:表单相关操作API属性渲染常规渲染定向渲染2.7+忽略渲染验证自定

热文推荐