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


    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; // 
            // 初始化队列
            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;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    841. 钥匙和房间

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

    思路:深搜三部曲

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

    本题代码:

    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;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    OLAP引擎也能实现高性能向量检索,据说QPS高于milvus!
    sapjco3.dll has version “721.619“, but required is at least version “721.913“
    动态规划 | 不同路径、整数拆分、不同的二叉搜索树 | leecode刷题笔记
    如何删除卸载苹果mac电脑应用软件没有残留垃圾
    【前端】Vue+Element UI案例:通用后台管理系统-项目总结
    CSDN编程挑战赛第六期——Python题解
    leetcode1358. 包含所有三种字符的子字符串数目
    HCIP学习--扩展知识点
    学生HTML个人网页作业作品:HTML绿色的化妆品静态网站(web前端网页制作课作业)
    华为机试真题 C++ 实现【完全二叉树非叶子部分后序遍历】
  • 原文地址:https://blog.csdn.net/weixin_41725662/article/details/132908236