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

127. 单词接龙 ★

文档讲解 :代码随想录 - 127. 单词接龙

状态:开始学习。(★:需要多次回顾并重点回顾)

思路:

本题需要解决两个问题:

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

另外注意点:

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

本题代码:

cpp 复制代码
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. 确认递归函数,参数

    cpp 复制代码
    // key 当前得到的可以 
    // visited 记录访问过的房间 
    void dfs(const vector<vector<int>>& rooms, int key, vector<bool>& visited) {
  2. 确认终止条件

    cpp 复制代码
    if (visited[key]) { // 本层递归是true,说明访问过,立刻返回
       return;
    }
  3. 处理目前搜索节点出发的路径

    cpp 复制代码
        for (int key : keys) { 
            if (visited[key] == false) { // 处理下一层节点,判断是否要进行递归
                visited[key] = true;
                dfs(rooms, key, visited);
            }       
        }

本题代码:

cpp 复制代码
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

思路:

遍历每一个空格,遇到岛屿,计算其上下左右的情况,遇到水域或者出界的情况,就可以计算边了。

本题代码:

cpp 复制代码
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;
    }
};
相关推荐
wx2004110212 分钟前
Codeforces Round 973 (Div. 2) - D题
数据结构·c++·算法
Crossoads1 小时前
【数据结构】排序算法---基数排序
c语言·开发语言·数据结构·算法·排序算法
爱敲代码的憨仔1 小时前
第二讲 数据结构
数据结构·算法
叫我Cow_1 小时前
【牛客】小白月赛101D-tb的平方问题
算法
卿卿qing1 小时前
【JavaScript】算法之贪心算法(贪婪算法)
算法
郭小儒1 小时前
VCNet论文阅读笔记
算法
尽蝶叙1 小时前
C++:分苹果【排列组合】
开发语言·c++·算法
所待.3832 小时前
小小扑克牌算法
java·算法
眰恦3742 小时前
数据结构--第六章图
数据结构·算法