图论(2)

130

和昨天的飞地类似,都是从最边缘的位置进行dfs/bfs,然后判断哪个点没有被遍历过

class Solution {
public:
    int dir[4][2]={1,0,-1,0,0,1,0,-1};
    void dfs(vector<vector<char>>& board,vector<vector<bool>>& visited,int x,int y)
    {
        for(int i=0;i<4;i++)
        {
            int nextx=x+dir[i][0];
            int nexty=y+dir[i][1];
            if(nextx<0||nexty<0||nextx>=board.size()||nexty>=board[0].size())
            {
                continue;
            }
            if(!visited[nextx][nexty]&&board[nextx][nexty]=='O')
            {
                visited[nextx][nexty]=true;
                dfs(board,visited,nextx,nexty);
            }
        }
    }
    void solve(vector<vector<char>>& board) {
        int m=board.size();
        int n=board[0].size();
        vector<vector<bool>> visited(m,vector<bool>(n,0));
        for(int i=0;i<m;i++)
        {
            if(!visited[i][0]&&board[i][0]=='O')
            {
                visited[i][0]=true;
                dfs(board,visited,i,0);
            }
            if(!visited[i][n-1]&&board[i][n-1]=='O')
            {
                visited[i][n-1]=true;
                dfs(board,visited,i,n-1);
            }
        }
        for(int j=0;j<n;j++)
        {
            if(!visited[0][j]&&board[0][j]=='O')
            {
                visited[0][j]=true;
                dfs(board,visited,0,j);
            }
            if(!visited[m-1][j]&&board[m-1][j]=='O')
            {
                visited[m-1][j]=true;
                dfs(board,visited,m-1,j);
            }
        }
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(!visited[i][j])
                {
                    board[i][j]='X';
                }
            }
        }

    }
};

417

还是从两边开始遍历,如果下一个格子的数字比当前的大,那么就说明整体是一个上升的趋势,
如果最后两个visited都有这个格子,就说明是两边都能流到岸边的地方,

class Solution {
public:
    int dir[4][2]={1,0,-1,0,0,1,0,-1};
    void bfs(vector<vector<int>>& heights,vector<vector<bool>>& visited,int x,int y)
    {
        queue<pair<int,int>> que;
        que.push({x,y});
        visited[x][y]=true;
        while(!que.empty())
        {
            auto cur=que.front();que.pop();
            for(int i=0;i<4;i++)
            {
                int nextx=cur.first+dir[i][0];
                int nexty=cur.second+dir[i][1];
                if(nextx<0||nexty<0||nextx>=heights.size()||nexty>=heights[0].size())
                {
                    continue;
                }
                if(!visited[nextx][nexty]&&heights[nextx][nexty]>=heights[cur.first][cur.second])
                {
                    visited[nextx][nexty]=true;
                    que.push({nextx,nexty});
                }
            }
        }
    }
    vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {
        int m=heights.size();
        int n=heights[0].size();
        vector<vector<int>> result;
        vector<vector<bool>> visitedByPac (m,vector<bool>(n,0));
        vector<vector<bool>> visitedByAtl (m,vector<bool>(n,0));
        for(int i=0;i<m;i++)
        {
            if(!visitedByPac[i][0])
            {
                visitedByPac[i][0]=true;
                bfs(heights, visitedByPac, i, 0);
            }
            if(!visitedByAtl[i][n-1])
            {
                visitedByAtl[i][n-1]=true;
                bfs(heights,visitedByAtl,i,n-1);
            }
        }
        for(int j=0;j<n;j++)
        {
            if(!visitedByPac[0][j])
            {
                visitedByPac[0][j]=true;
                bfs(heights, visitedByPac, 0, j);
            }
            if(!visitedByAtl[m-1][j])
            {
                visitedByAtl[m-1][j]=true;
                bfs(heights,visitedByAtl,m-1,j);
            }
        }
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(visitedByAtl[i][j]&&visitedByPac[i][j])
                {
                    result.push_back({i,j});
                }

            }
        }
        return result;

    }
};

827最大人工岛

一开始的思路:

  1. 遍历一遍岛屿,看看谁最大,记录一下(但这一步好像可以省略)
  2. 遍历0,每变一个,都从这个点开始广搜,计算面积,最后返回最大面积
    复杂度n^6,果不其然n=350的时候接近1亿次,直接爆了
    看了一下别人的思路:
  3. 遍历整个grid,把每一块陆地都拿出来然后计算大小,用序号标到原来的grid上,并用一个map存储序号和面积
  4. 遍历0,每变一个都去看周围的面积加起来是否更大,
class Solution {
public:
    /*
    如何暴力:
    1. 统计所有岛中最大的岛
    2. 遍历所有0,看看把这个0变成1之后是否附近会出现更大的岛
    3. 复杂度:n^4,n<=500可以试试
    完了包了n=358就爆了接近1亿次了不爆才怪啊尼玛
    */
    /*
    看了别人的一点思路:
    用map记录岛屿面积和给他编号
    遍历0的时候就把他周围的编号加上就行
    */
    int dir[4][2]={1,0,-1,0,0,1,0,-1};
    int bfs(vector<vector<int>>& grid,vector<vector<bool>>& visited,int x,int y,int islandNo)
    {
        int island=1;
        queue<pair<int,int>> que;
        que.push({x,y});
        visited[x][y]=true;
        grid[x][y]=islandNo;
        while(!que.empty())
        {
            auto cur=que.front();
            que.pop();
            for(int i=0;i<4;i++)
            {
                int nextx=cur.first+dir[i][0];
                int nexty=cur.second+dir[i][1];
                if(nextx<0||nexty<0||nextx>=grid.size()||nexty>=grid.size())
                {
                    continue;
                }
                if(!visited[nextx][nexty]&&grid[nextx][nexty]==1)
                {
                    visited[nextx][nexty]=true;
                    que.push({nextx,nexty});
                    grid[nextx][nexty]=islandNo;
                    island++;
                }
            }
        }
        return island;
    }
    
    int largestIsland(vector<vector<int>>& grid) {
        int n = grid.size();
        vector<vector<bool>> visited(n, vector<bool>(n, 0));
        //使用map来记录一下岛屿面积吧
        unordered_map<int,int> mymap;
        // 1.遍历最大岛
        int islandNo=0;
        int maxisland=0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1 && !visited[i][j]) {
                    islandNo++;
                    int area=bfs(grid,visited,i,j,islandNo);
                    mymap.emplace(islandNo,area);
                    maxisland = max(maxisland, area);
                }
            }
        }
        //2.遍历0
         for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if(grid[i][j]==0)
                {
                    int area=1;
                    set<int> No;
                    for(int k=0;k<4;k++)
                    {
                        int nextx=i+dir[k][0];
                        int nexty=j+dir[k][1];
                        if(nextx<0||nexty<0||nextx>=grid.size()||nexty>=grid.size())
                        {
                            continue;
                        }
                        if(grid[nextx][nexty]!=0)
                        {
                            No.insert(grid[nextx][nexty]);
                        }
                        
                    }
                    for(auto k=No.begin();k!=No.end();k++)
                    {
                        area+=mymap[*k];
                    }
                    maxisland = max(maxisland, area);
                }
            }
        }
        
        return maxisland;
    }
};
posted @ 2024-01-11 14:04  LiviaYu  阅读(10)  评论(0)    收藏  举报