面试笔试算法系列之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; }
相关文章推荐
- 机器学习笔试面试系列算法集锦
- 机器学习笔试面试系列算法集锦
- [置顶] 机器学习笔试面试系列算法集锦
- 程序员笔试面试算法题系列--数组
- 面试笔试算法系列之分治法
- C/C++面试之算法系列--几个典型的内存拷贝及字符串函数实现
- C/C++面试之算法系列--二维动态数组定义及二维静态数组与**P的区别
- 面试笔试系列之二 链表相关
- 面试笔试系列之三 字符串相关
- C/C++面试之算法系列--菲波拉契数列的递归与非递归算法
- C/C++面试之算法系列--如何利用数学思想解1/2/5组合问题
- C/C++面试之算法系列--不申请变量和空间反转字符串
- C/C++面试之算法系列--约瑟夫环:每隔两个循环删除数组元素,求最后删除者的下标问题
- Java常见笔试面试题目深度剖析系列之:Java方法参数传递详解
- C/C++面试之算法系列--快速计算32位数中1的位数
- C/C++面试之算法系列--借刀杀人,不使用任何中间变量实现strlen
- C/C++面试之算法系列--时间复杂度为o(N)查找1至N-1构成的a[N]重复元素
- 面试笔试系列之一 c与c++ static关键字解析
- C/C++面试之算法系列--整数数组的循环右移
- Java常见笔试面试题目深度剖析系列之:Java方法参数传递详解