[LEETCODE][305. Number of Islands II]

先来看一下题目描述:

305. Number of Islands II

A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand operation which turns the water at position (row, col) into a land. Given a list of positions to operate, count the number of islands after each addLand operation. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

Example:

Input: m = 3, n = 3, positions = [[0,0], [0,1], [1,2], [2,1]]
Output: [1,1,2,3]

Explanation:

Initially, the 2d grid grid is filled with water. (Assume 0 represents water and 1 represents land).

0 0 0
0 0 0
0 0 0

Operation #1: addLand(0, 0) turns the water at grid[0][0] into a land.

1 0 0
0 0 0   Number of islands = 1
0 0 0

Operation #2: addLand(0, 1) turns the water at grid[0][1] into a land.

1 1 0
0 0 0   Number of islands = 1
0 0 0

Operation #3: addLand(1, 2) turns the water at grid[1][2] into a land.

1 1 0
0 0 1   Number of islands = 2
0 0 0

Operation #4: addLand(2, 1) turns the water at grid[2][1] into a land.

1 1 0
0 0 1   Number of islands = 3
0 1 0

Follow up:

Can you do it in time complexity O(k log mn), where k is the length of the positions?

那么 先放上我写的代码:

//每次在指定位置将0变成1,之后返回islands的数目
//考虑从1开始上色,如果当前位置的四周有相邻的,直接进行相连即可,否则上的颜色+1
//题目里面可能会给重复上色的区域
class Solution {
public:
    vector<int> numIslands2(int m, int n, vector<vector<int>>& positions) {
        vector<vector<int>> grid(m,vector<int>(n,0)); //grid网格
        for(auto pos:positions){
            int x=pos[0],y=pos[1]; //当前添加点的坐标
            if(color.size()==0){ //第一次的话,肯定需要进行赋值
                grid[x][y]=1;
                color.insert(1);
                res.push_back(1);
                for_record=1;
                continue;
            }
            int min_color=min(min(check(grid,x-1,y),check(grid,x+1,y)),min(check(grid,x,y-1),check(grid,x,y+1)));
            if(min_color==INT_MAX && grid[x][y]==0){ //如果未进行过上色,继续上色,这里要判重复值!
                grid[x][y]=++for_record; //记录颜色先来进行增加
                color.insert(grid[x][y]);
                res.push_back(color.size());
            }
            else{ //否则我们以最小颜色进行修改
                grid[x][y]=min_color;
                dfs(grid,x-1,y,min_color);
                dfs(grid,x+1,y,min_color);
                dfs(grid,x,y-1,min_color);
                dfs(grid,x,y+1,min_color);
                res.push_back(color.size());
            }
        }
        return res;
    }
private:
    set<int> color; //记录使用的颜色
    vector<int> res; //最终结果
    int for_record=0; //记录颜色,如果仅仅按照color的size的话可能会出现重复值
    
    int check(vector<vector<int>>& grid,int x,int y){
        if(!isValid(grid,x,y) || grid[x][y]==0) //超出边界或者未上色
            return INT_MAX;
        return grid[x][y]; //否则返回之前的上色值
    }

    bool isValid(vector<vector<int>>& grid,int x,int y){
        if(x<0 || x>=grid.size() || y<0 || y>=grid[0].size())
            return false;
        return true;
    }
    
    void dfs(vector<vector<int>>& grid,int x,int y,int c){
        if(!isValid(grid,x,y) || grid[x][y]==0) //超出边界
            return;
        if(grid[x][y]==c) //进行过上色的返回
            return;
        if(grid[x][y]!=0 && grid[x][y]!=c){ //碰到了之前上其他颜色的,进行修改
            if(color.count(grid[x][y])) //把原来的颜色删除
                color.erase(grid[x][y]);
            grid[x][y]=c;
        }
        dfs(grid,x+1,y,c);
        dfs(grid,x-1,y,c);
        dfs(grid,x,y-1,c);
        dfs(grid,x,y+1,c);
    }
};

在做题当中的几个问题:

现在对于dfs的小岛问题,有点喜欢用上色来做,并且很多时候可以用一个set来记录使用过的颜色

1.对于这道题,一开始也是相同的思路,我想用set.size()来直接进行记录更新颜色,但是总是WA,想了一下,因为我在改变颜色的时候,如果仅仅使用set.size(),无法避免重复值的产生,可能明明不想连的两块,由于颜色大小的改变,同时变成了相同的颜色,这是不允许的!!!因此我再增加一个变量for_record来进行记录颜色,这样可以保证颜色永远不会重复!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值