图论(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最大人工岛
一开始的思路:
- 遍历一遍岛屿,看看谁最大,记录一下(但这一步好像可以省略)
- 遍历0,每变一个,都从这个点开始广搜,计算面积,最后返回最大面积
复杂度n^6,果不其然n=350的时候接近1亿次,直接爆了
看了一下别人的思路: - 遍历整个grid,把每一块陆地都拿出来然后计算大小,用序号标到原来的grid上,并用一个map存储序号和面积
- 遍历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;
}
};

浙公网安备 33010602011771号