这个题目是很霸气的,这是一道算法题。
给定一个棋盘,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。
好了,感谢作者,虽然我忘记了是哪个网址,但是很感谢。