代码随想录| 图论03●827最大人工岛 ●127单词接龙 ●841钥匙和房间 ●463 岛屿的周长

#827最大人工岛 Hard

自己没想出来。

#127单词接龙 Hard

#841钥匙和房间

比较好做

void bfs(vector>& rooms,vector &v){
        queue que;
        que.push(0);
        v[0]=true;
        while(!que.empty()){
            int cur=que.front();que.pop();
            for(int i=0;i>& rooms) {
        vector v(rooms.size(),false);
        bfs(rooms,v);
        for(int i=0;i

 和随想录一样下面这样写好点,含义清晰,不容易出错。我的写法:v[rooms[cur][i]] 粗心很容易出错,我一开始就写的 v[i] 完全不对

         int key = que.front(); que.pop();
         vector keys = rooms[key];
         for (int key : keys) {
             if (!visited[key]) {
                 que.push(key);
                 visited[key] = 1;
             }
         }

“另外,关于是否需要回溯:本题是需判断 0节点是否能到所有节点,那么我们就没有必要回溯去撤销操作了,只要遍历过的节点一律都标记上。那什么时候需要回溯操作呢?当我们需要搜索一条可行路径的时候,就需要回溯操作了,因为没有回溯,就没法“调头”, 可见题目797.”


#463 岛屿的周长 esay 

但我觉得没有很easy。"岛屿问题最容易让人想到BFS或者DFS,但是这道题还真没必要,别把简单问题搞复杂了"

我的思路:看每行每行,有一个连续的块 就sum+2,看每列每列,有一个连续的块就sum+2

int islandPerimeter(vector>& grid) {
    int sum = 0;
    int n = grid.size();
    int m = grid[0].size();

    for(int i = 0; i < n; i++) {
        bool block_found = false;
        for(int j = 0; j < m; j++) {
            if(grid[i][j] == 1) {
                if(!block_found) {
                    sum += 2;
                    block_found = true;
                }
            } else {
                block_found = false;  // reset flag if we encounter a 0
            }
        }
    }

    for(int j = 0; j < m; j++) {
        bool block_found = false;
        for(int i = 0; i < n; i++) {
            if(grid[i][j] == 1) {
                if(!block_found) {
                    sum += 2;
                    block_found = true;
                }
            } else {
                block_found = false;  // reset flag if we encounter a 0
            }
        }
    }

    return sum;
}

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

int direction[4][2] = {0, 1, 1, 0, -1, 0, 0, -1};
    int islandPerimeter(vector>& 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:方块数*4-内在的边*2。我本来也想这么做,但是我算内在的边是按照dfs bfs算的,就不对,会漏掉。不要按dfs bfs来,要按普通遍历,然后只看左下或右上

int islandPerimeter(vector>& 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;
    }

你可能感兴趣的:(代码随想录一刷,图论,leetcode,算法,c++,深度优先)