一片海洋中的陆地


这个题目是很霸气的,这是一道算法题。


给定一个棋盘,n*n大小,可以把它想象成一片海洋,每个格子里面是0或者1,0代表海水,1代表土壤,求海洋中陆地的块数。


今晚吃晚饭时听学长分享了这个面试题,于是回来寻思着怎么做。

说实话,这个题目昨晚和学长交谈时有DFS的想法,回来却不敢去实现,看了leetcode上有一道一模一样的题目,看了别人的分享答案。

这个问题就是遍历每一个节点【把每个棋格当做是节点吧】,对每个节点发起DFS,如果是1就把这个1置为0,然后对这个节点的四周是1的节点进行DFS,搜完之后把结果

result++。


上代码:

class Solution {
public:
    int numIslands(vector<vector<char>> &grid) {
        int ret = 0;
        if(grid.empty() || grid[0].empty())
            return ret;
        int m = grid.size();
        int n = grid[0].size();
        for(int i = 0; i < m; i ++)
        {
            for(int j = 0; j < n; j ++)
            {
                if(grid[i][j] == '1')
                {
                    dfs(grid, i, j, m, n);
                    ret ++;
                }
            }
        }
        return ret;
    }
    
    void dfs(vector<vector<char>> &grid, int i, int j, int m, int n)
    {
        stack<Node*> stk;
        Node* rootnode = new Node(i, j);
        grid[i][j] = '0';
        stk.push(rootnode);
        while(!stk.empty())
        {
            Node* top = stk.top();
            if(top->x > 0 && grid[top->x-1][top->y] == '1')
            {//check up
                grid[top->x-1][top->y] = '0';
                Node* upnode = new Node(top->x-1, top->y);
                stk.push(upnode);
                continue;
            }
            if(top->x < m-1 && grid[top->x+1][top->y] == '1')
            {//check down
                grid[top->x+1][top->y] = '0';
                Node* downnode = new Node(top->x+1, top->y);
                stk.push(downnode);
                continue;
            }
            if(top->y > 0 && grid[top->x][top->y-1] == '1')
            {//check left
                grid[top->x][top->y-1] = '0';
                Node* leftnode = new Node(top->x, top->y-1);
                stk.push(leftnode);
                continue;
            }
            if(top->y < n-1 && grid[top->x][top->y+1] == '1')
            {//check right
                grid[top->x][top->y+1] = '0';
                Node* rightnode = new Node(top->x, top->y+1);
                stk.push(rightnode);
                continue;
            }
            stk.pop();
        }
    }
};

这个是非递归版本。代码中DFS查找是把节点前后左右的1压栈,一一处理,直到栈里已经没有1处理了,所以是一个很容易想到的处理方法,对了,别忘了,处理完一个节点后pop出栈。


接下来上递归版本的代码:


class Solution {
public:
    int numIslands(vector<vector<char>> &grid) {
        int ret = 0;
        if(grid.empty() || grid[0].empty())
            return ret;
        int m = grid.size();
        int n = grid[0].size();
        for(int i = 0; i < m; i ++)
        {
            for(int j = 0; j < n; j ++)
            {
                if(grid[i][j] == '1')
                {
                    dfs(grid, i, j, m, n);
                    ret ++;
                }
            }
        }
        return ret;
    }
    
    void dfs(vector<vector<char>> &grid, int i, int j, int m, int n)
    {
        grid[i][j] = '0';
        if(i > 0 && grid[i-1][j] == '1')
            dfs(grid, i-1, j, m, n);
        if(i < m-1 && grid[i+1][j] == '1')
            dfs(grid, i+1, j, m, n);
        if(j > 0 && grid[i][j-1] == '1')
            dfs(grid, i, j-1, m, n);
        if(j < n-1 && grid[i][j+1] == '1')
            dfs(grid, i, j+1, m, n);
    }
};

这种递归版本比较简单,把节点置为0后对周围是1的节点发起DFS。


好了,感谢作者,虽然我忘记了是哪个网址,但是很感谢。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值