题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
题目描述:有 n 个房间,房间按从 0 到 n - 1 编号。最初,除 0 号房间外的其余所有房间都被锁住。你的目标是进入所有的房间。然而,你不能在没有获得钥匙的时候进入锁住的房间。
当你进入一个房间,你可能会在里面找到一套不同的钥匙,每把钥匙上都有对应的房间号,即表示钥匙可以打开的房间。你可以拿上所有钥匙去解锁其他房间。
给你一个数组 rooms 其中 rooms[i] 是你进入 i 号房间可以获得的钥匙集合。如果能进入 所有 房间返回 true,否则返回 false。
解题思路(广度优先遍历):
这题需要注意,本题是一道有向图的题,前面的题基本上都是无向图。首先,将第一个房间的钥匙进队,然后当队列不为空时,不断出队。打开对应的门,拿钥匙,如果之前这个门已经开过了。就直接continue。否则就将这个钥匙能开的门入队。
- class Solution {
- public:
- bool canVisitAllRooms(vector<vector<int>>& rooms) {
- vector<bool> visited(rooms.size(),false);//来记录我们能打开的门
- queue<vector<int>> que;//存储能打开的门的钥匙组
- que.push(rooms[0]);
- while(!que.empty()){
- vector<int> tmp = que.front();
- que.pop();
- for(int i=0;i<tmp.size();i++){
- if(visited[tmp[i]] == false){//若这门被开过了,直接跳过,不然可能会死循环
- que.push(rooms[tmp[i]]);
- visited[tmp[i]] = true;
- }
- }
- }
- for(int i=1;i<rooms.size();i++){
- if(visited[i] == false) return false;
- }
- return true;
- }
- };
总结:
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
题目描述:给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。
网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。
岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。
解题思路
思路一:
遍历所有的格子,首先判断不是陆地就continue,是陆地我们就对其四个方向进行侦测,若是海洋或边界则说明这个方向对应的有一个边可以当作周长加上。即res++。
- 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;
- }
- };
思路二:
通过观察可以看出来,只要有一对岛屿挨在一起,那么其总周长就应该减2。故我们只需要判断当前点是否有挨着岛屿即可,有则面积-2。注意,我们只需要讨论 左边和上边 或 右边和下边 即可。因为会遍历所有的岛屿,防止重复遍历了。
- class Solution {
- public:
- int islandPerimeter(vector<vector<int>>& grid) {
- int sum = 0; // 陆地数量
- int cover = 0; // 相邻数量
- for (int i = 0; i < grid.size(); i++) {
- for (int j = 0; j < grid[0].size(); j++) {
- if (grid[i][j] == 1) {
- sum++;
- // 统计上边相邻陆地
- if(i - 1 >= 0 && grid[i - 1][j] == 1) cover++;
- // 统计左边相邻陆地
- if(j - 1 >= 0 && grid[i][j - 1] == 1) cover++;
- // 为什么没统计下边和右边? 因为避免重复计算
- }
- }
- }
- return sum * 4 - cover * 2;
- }
- }
总结: