图论基础|841.钥匙和房间、463. 岛屿的周长

目录

841.钥匙和房间

思路:本题是一个有向图搜索全路径的问题。 只能用深搜(DFS)或者广搜(BFS)来搜。

463. 岛屿的周长


841.钥匙和房间

力扣题目链接

(opens new window)

有 N 个房间,开始时你位于 0 号房间。每个房间有不同的号码:0,1,2,...,N-1,并且房间里可能有一些钥匙能使你进入下一个房间。

在形式上,对于每个房间 i 都有一个钥匙列表 rooms[i],每个钥匙 rooms[i][j] 由 [0,1,...,N-1] 中的一个整数表示,其中 N = rooms.length。 钥匙 rooms[i][j] = v 可以打开编号为 v 的房间。

最初,除 0 号房间外的其余所有房间都被锁住。

你可以自由地在房间之间来回走动。

如果能进入每个房间返回 true,否则返回 false。

示例 1:

  • 输入: [[1],[2],[3],[]]
  • 输出: true
  • 解释: 我们从 0 号房间开始,拿到钥匙 1。 之后我们去 1 号房间,拿到钥匙 2。 然后我们去 2 号房间,拿到钥匙 3。 最后我们去了 3 号房间。 由于我们能够进入每个房间,我们返回 true。

示例 2:

  • 输入:[[1,3],[3,0,1],[2],[0]]
  • 输出:false
  • 解释:我们不能进入 2 号房间。

思路:本题是一个有向图搜索全路径的问题。 只能用深搜(DFS)或者广搜(BFS)来搜。

//深度优先
class Solution {
public:
void dfs(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);
            }
        }
    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;
    }
};

//广度优先版
class Solution {
public:
    bool bfs(vector<vector<int>>& rooms){
        vector<int>visited(rooms.size(),0);
        queue<int>que;
        visited[0]=1;//初始化,从第一个房间‘0’开始
        que.push(0);
        while(!que.empty()){
            int key =que.front();que.pop();
            vector<int>keys=rooms[key];
            for(int key: keys){
                if(!visited[key]){
                    que.push(key);
                    visited[key]=1;
                }
            }
       }
       for(int i:visited){
        if(!i)return false;
       }
       return true;

    }
    bool canVisitAllRooms(vector<vector<int>>& rooms) {
        return bfs(rooms);
    
    }
};

463. 岛屿的周长

力扣题目链接

给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。

网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。

岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。

  • 输入:grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
  • 输出:16
  • 解释:它的周长是上面图片中的 16 个黄色的边

示例 2:

  • 输入:grid = [[1]]
  • 输出:4

示例 3:

  • 输入:grid = [[1,0]]
  • 输出:4

思路:遍历地图,遇到岛屿,遍历其上下左右四个方向,如果遇到边界或者遇到水域(grid[nextx][nexty]=0),result++;

class Solution {
public:
    int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};

    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 nextx = i + dir[k][0];
                        int nexty = j + dir[k][1];

                        if (nextx < 0 || nextx >= grid.size() || nexty < 0 ||
                            nexty >= grid[0].size() ||
                            grid[nextx][nexty] ==
                                0) { // 遇到边界或者水域,周长++;
                            result++;
                        }
                    }
                }
            }
        }
        return result;
    }
};

参考:代码随想录

  • 25
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值