图论第2天|417 827 127 841 463 1971 684

417 因为边一定会流向大海 分为太平洋和大西洋 写两个visited数组来先标记边

用dfs来辐射到会流向海洋的陆地 (未被标记过&&与已标记的相邻&&比已标记的高或相等)

class Solution {
private:
    int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
    void dfs (vector>& heights, vector>& visited, int x, int y) {
        visited[x][y] = true;
        for (int i=0; i<4; i++) {
            int nx = x+dir[i][0];
            int ny = y+dir[i][1];
            if (nx<0 || nx>=heights.size() || ny<0 || ny>=heights[0].size()) continue;
            if (!visited[nx][ny] && heights[nx][ny]>=heights[x][y]) {
                dfs(heights, visited, nx, ny);
            }
        }
    }
public:
    vector> pacificAtlantic(vector>& heights) {
        vector> pacific(heights.size(), vector(heights[0].size(), false));
        vector> atlantic(heights.size(), vector(heights[0].size(), false));

        for (int i=0; i> result;
        for (int i=0; i curr = {i, j};
                    result.push_back(curr);
                }
            }
        }
        return result;
    }
};

827 把每个岛屿标记成不同的数 并记录他们的大小 放在一个map里面 

遍历全部0 把它变成1之后加上四周岛屿数量 (注意不要加重复了)最后得出最大的岛屿

class Solution {
private:
    int dir[4][2]= {{0,1},{1,0},{0,-1},{-1,0}};
    int dfs (vector>& grid, vector>& visited, int x, int y, int mark) {
        visited[x][y] = mark;
        int count =1;
        for (int i=0; i<4; i++) {
            int nx=x+dir[i][0];
            int ny=y+dir[i][1];
            if (nx<0 || nx>=grid.size() || ny<0 || ny>=grid[0].size()) continue;
            if (visited[nx][ny]!=0 || grid[nx][ny]==0) continue;
            count+=dfs(grid, visited, nx, ny, mark);
        }
        return count;
    }
public:
    int largestIsland(vector>& grid) {
        vector> visited (grid.size(), vector (grid[0].size(), 0));
        int mark = 2;
        unordered_map umap;
        umap[0]=0;
        for (int i=0; i mark_set;
                for (int k=0; k<4; k++) {
                    int ni=i+dir[k][0];
                    int nj=j+dir[k][1];
                    if (ni<0 || ni>=grid.size() || nj<0 || nj>=grid[0].size()) continue;
                    int curr_mark = visited[ni][nj];
                    mark_set.insert(curr_mark);
                }
                for (int curr_mark:mark_set) {
                    connected_num+=umap[curr_mark];
                }
                result = max(result, connected_num);
            }
        }
        if (result==0) return grid.size()*grid[0].size();
        return result;
    }
};

127 先确定思路:找最短路径用广搜;相邻单词只能差一个字符 像岛屿问题中去上下左右坐标差一 但在这里就不止四个方向 而是有wordList[i].size() * 26个可能 那就遍历这些肯能并在wordList当中查找(先将wordList变成wordSet会比较好找

记得要标记找过的路径 这里的visited的值就可以是到达该单词的最短路径 用一个unordered_map来写

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector& wordList) {
        unordered_set wordSet (wordList.begin(), wordList.end());
        if (wordSet.find(endWord)==wordSet.end()) return 0;

        queue que;
        que.push(beginWord);
        unordered_map visited;
        visited.insert({beginWord, 1});

        while (!que.empty()) {
            string curr_word = que.front(); que.pop();
            for (int i=0; i

841 广搜/深搜所有房间 去过的标记visited 这里直接写的广搜 对于当前每个房间 下一层是当前房间的所有钥匙可去的地方

class Solution {
public:
    bool canVisitAllRooms(vector>& rooms) {
        queue que;
        que.push(0);
        vector visited(rooms.size(), false);
        visited[0]=true;
        while (!que.empty()) {
            int curr_room = que.front(); que.pop();
            for (int i=0; i

463 求周长直接遍历每个陆地 看他四周是否是海 如果是那边+1 或者是边界也+1

class Solution {
public:
    int islandPerimeter(vector>& grid) {
        int result = 0;
        int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
        for (int i=0; i=grid.size() || nj<0 || nj>=grid[0].size()) result++;
                        else if (grid[i+dir[k][0]][j+dir[k][1]]!=1) result++;
                    }
                }
            }
        }
        return result;
    }
};

1971 并查集模版题

class Solution {
private:
    int n=200000;
    vector father = vector(n, 0);
    void init() {
        for (int i=0; i>& edges, int source, int destination) {
        init();
        for (int i=0; i

684 main function里面因为要return最后一个可以删除的边 那就从前往后加边 如果发现要加的这个边本来就是连通的说明就不要加这个边 return

不是很明白为什么n要比给定的节点数量最大值大一点(刚好取1000真的会有corner case过不去

class Solution {
private:
    int n=1005;
    vector father = vector (n, 0);
    void init() {
        for (int i=0; i findRedundantConnection(vector>& edges) {
        init();
        for (int i=0; i

你可能感兴趣的:(深度优先,算法)