赞
踩
所有可能的路径:给你一个有 n
个节点的 有向无环图(DAG),请你找出所有从节点 0
到节点 n-1
的路径并输出(不要求按特定顺序)
graph[i]
是一个从节点 i
可以访问的所有节点的列表(即从节点 i
到节点 graph[i][j]
存在一条有向边)。
其实dfs的过程就是回溯算法的过程,框架是相通的
- void dfs(参数) {
- if (终止条件) {
- 存放结果;
- return;
- }
-
- for (选择:本节点所连接的其他节点) {
- 处理节点;
- dfs(图,选择的节点); // 递归
- 回溯,撤销处理结果
- }
- }
1.确定递归函数及参数
在该题中,递归函数的参数是graph二维数组跟当前结点x。
2. 确定终止条件
终止条件是当目前搜索到的路径没有下一个能访问的结点时,将该路径结果存储。所以终止条件是该结点为graph数组的最后一个元素。
3.处理目前搜索节点出发的路径
每一次搜索中,先找当前节点x的邻接点有哪些,故遍历该结点的邻接结点graph[x][i],在每一轮遍历中,将一个邻接点加入当前路径。再以邻接点为当前结点x,继续深搜,进入下一层递归,当递归结束并保存了遍历路径时,再进行回溯,撤销本节点。
- class Solution {
- public:
- vector<vector<int>> result;
- vector<int> path;
- vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
- path.push_back(0);
- dfs(graph,0);//当前结点是0
- return result;
- }
-
- void dfs(vector<vector<int>>& graph,int x)
- {
- //找出所有从节点 0 到节点 n-1 的路径,故graph.size()-1为结点个数
- if(x == graph.size()-1)
- {
- result.push_back(path);
- return ;
- }
-
- for(int i=0 ;i < graph[x].size() ; i++)
- {
- path.push_back(graph[x][i]);
- dfs(graph,graph[x][i]);
- path.pop_back();
- }
- }
- };
给你一个由 '1'
(陆地)和 '0'
(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
1.确定递归函数及参数
在该题中,递归函数的参数是graph二维数组/当前结点x,y/是否访问过数组visted。
2. 确定终止条件
处理函数numIslands中,我们对没有访问过的陆地结点先进行计数,每计数一次,则把该结点的连通节点全部标为ture,即已访问过。在后续的计数过程中不计入这些连通结点。终止条件是当目前搜索到的路径没有下一个能访问的结点时(即当前节点已经访问过或者当前节点是海洋而不是陆地)。
3.处理目前搜索节点出发的路径
每一次搜索中,先访问结点(x,y)并将对应的visited数据元素置为true,然后深度搜索该结点的的正下方结点,再将该结点变为当前结点x,置为true后继续深搜,进入下一层递归,当递归结束后,再搜索当前结点的右/上/左边的结点并分别深搜。
- class Solution {
- public:
- int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 四个方向
- int numIslands(vector<vector<char>>& grid) {
- int n = grid.size(), m = grid[0].size();
- vector<vector<char>> visited(n,vector<char>(m,false));//是否已访问过
-
- int res = 0;//岛屿数量
- for(int i=0; i<n; i++)
- for(int j=0; j<m; j++)
- {
- if(!visited[i][j] && grid[i][j] == '1')//未访问过而且是陆地不是海
- {
- res++;//岛屿数量加一
- dfs(grid,visited,i,j);//将这块陆地的邻接陆地全标为true,不参与下次的遍历
- }
- }
- return res;
- }
-
- void dfs(vector<vector<char>>& grid,vector<vector<char>>& visited,int x,int y)
- {
- //深度遍历 x,y 结点的邻接点,将这些节点设为 访问过
- if(grid[x][y] == '0' || visited[x][y])//访问过此节点或碰到海水
- return;
- visited[x][y] = true;
- for(int i = 0; i < 4; i++)
- {
- int nextx = x + dir[i][0];
- int nexty = y + dir[i][1];
- if(nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size())
- continue;//越界,查看往其他地方走能不能行
- dfs(grid,visited,nextx,nexty);
-
- }
- }
- };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。