您的位置:首页 > 职场人生

面试笔试算法系列之DFS

2017-05-08 02:44 330 查看

面试笔试算法系列之DFS

DFS:(Depth First Search)数据结构中定义为一种最简单和直接的图搜索算法,主要步骤就是从起点尽可能的深入,每次试图访问之前没有访问过的节点,如果没有这样的节点存在会回退至上个节点。

问题举例:

1. 2017滴滴春招笔试题

这道题来自LeetCode的Number of Islands,滴滴笔试题的中文题目如下

使用二维矩阵中的0和1模拟水和岛,岛是1组成的区域(上下左右相邻的1是同一片岛屿),岛屿四周被水环绕。
比如:
11110
11010
11000
00000
其中岛屿有1个
11000
11000
00100
00011
其中岛屿有3个


输入:
第一行输入一个数m代表行数,第二行输入一个数n列数,(0<m,n<10),接下来的m行输入矩阵内容,
4
4
11000
11000
00100
00011


输出:
岛屿数
3


初步分析:可以看出,大概思路就是从左到右,从上到下,找到1之后,继续查看当前的1的上下左右是否存在新的1,存在的话就归为岛屿的一部分,不存在就进入下一个遍历。这正是一个DFS的解决场景。

代码思路分析:

最外层循环遍历所有的点,i:1—>m,j:1—>n,

设置一个DFS函数,传入二维矩阵grid,

判断grid的第i行j列是不是1,

如果不是的话,就不是岛屿,继续下一个寻找,j++

如果是1的话,进入递归DFS判断它的上下左右的位置是不是1,并且当前节点已经被访问了,置为0。这个1被发现的时候,这次已经说明了这个区域是个岛屿,所以岛屿计数+1。

核心代码:

void DFS(vector<vector<char>> &grid, int i, int j) {
//判断越界
if (i < 0 || j < 0 || i >= grid.size() || j >= grid[0].size()) return;
//不是岛屿部分的话直接终止
if ('0' == grid[i][j]) return;

//当前是不是岛屿已经被确认了,置为0,不影响下次判断是不是岛屿
grid[i][j] = '0';

//递归查看上下左右的节点是不是岛屿
DFS(grid, i - 1, j);
DFS(grid, i + 1, j);
DFS(grid, i, j - 1);
DFS(grid, i, j + 1);
}

int numIslands(vector<vector<char>> &grid) {
int counter = 0;
for (int i = 0; i < grid.size(); ++i)
for (int j = 0; j < grid[i].size(); ++j)
//查看1至少是一个岛屿,增加1
if ('1' == grid[i][j]) {
++counter;
//进入递归
DFS(grid, i, j);
}
return counter;
}


完整源码

#include <iostream>
#include <vector>
using namespace std;

void DFS(vector<vector<char>> &grid, int i, int j) {
if (i < 0 || j < 0 || i >= grid.size() || j >= grid[0].size()) return;
if ('0' == grid[i][j]) return;
grid[i][j] = '0';
DFS(grid, i - 1, j);
DFS(grid, i + 1, j);
DFS(grid, i, j - 1);
DFS(grid, i, j + 1);
}

int numIslands(vector<vector<char>> &grid) {
int counter = 0;
for (int i = 0; i < grid.size(); ++i)
for (int j = 0; j < grid[i].size(); ++j)
if ('1' == grid[i][j]) {
++counter;
DFS(grid, i, j);
}
return counter;
}

int main() {
int m,n;
cin>>m>>n;
string temp_str; //临时存储字符串接收输入
vector<vector<char>> grid(m, vector<char>(n));  //二维向量的定义

for (int i = 0; i < m; i++) {
cin>>temp_str;
for (int j = 0; j < n; j++) {
grid[i][j]=temp_str[j];
}
}
cout << numIslands(grid) << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息