概念

如上图所示,对于每次搜索而言尽可能往深度前进,直到结点v的所有出发边都被找到然后回溯。通常用递归实现,遍历结果依赖每次选择遍历子结点的顺序。
LeetCode之深度优先搜索
332.Reconstruct Itinerary
重建飞行旅程,给定n段起点终点旅程,输出飞行目的地的先后顺序,从”JFK”为最初起点,可以返回飞行,若有多个答案,输出字典小序的那个。
Input: [[“MUC”, “LHR”], [“JFK”, “MUC”], [“SFO”, “SJC”], [“LHR”, “SFO”]]
Output: [“JFK”, “MUC”, “LHR”, “SFO”, “SJC”]
- 由于一开始没有理解可以返回飞这一点,错误的认为这是一道拓扑排序题目
- 后来发现对于有向图中的环也要遍历到每一条边后,可以用DFS来遍历,每次遍历完一个节点后在路径前部推入新的地点
- 由于需要考虑到单词顺序,在建图的时候,邻接表中用优先队列(最小堆)来存储邻接节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| var PriorityQueue = require('./PriorityQueue'); var findItinerary = function (tickets) { var res = [], neighbors = {}; for (var i = 0; i < tickets.length; i++) { if (neighbors[tickets[i][0]] == undefined) { neighbors[tickets[i][0]] = new PriorityQueue(function comparator(s1, s2) { return s1 > s2; }); } neighbors[tickets[i][0]].push(tickets[i][1]); } var start = 'JFK'; DFS(neighbors, res, start); return res; };
var DFS = function (neighbors, res, start) { while (neighbors[start] !== undefined && neighbors[start].size() > 0) { var newStart = neighbors[start].pop(); DFS(neighbors, res, newStart);
} res.unshift(start); };
|
366.Find Leaves of Binary Tree
将二叉树中的叶子节点一层层构建出数组(每当去掉一层叶子后出现新的叶子)进行输出。
Input:
1
/ \
2 3
/ \
4 5
OutPut: [[4, 5, 3], [2], [1]]
这道题目的关键在于每次要找到叶子节点,也就是说需要深度优先遍历到叶子,然后用记录当前高度来对应数组的存储位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| var BinaryTree = require('./BinaryTree'); var findLeaves = function (root) { var res = []; maxHeight(root, res); return res; };
function maxHeight(root, res) { if (root === null) return 0; var height = Math.max(maxHeight(root.left, res), maxHeight(root.right, res)) + 1; if (res.length < height) { res.push([]); } res[height - 1].push(root.val); return height; }
|
490.The Maze
给定二维迷宫、起点和终点,0表示空格,1表示墙,即障碍物,四周也是墙。球从起点出发后,可上下左右移动,每次都要沿一个方向撞墙为止。判断是否可到达指定终点。
Input 1:
0 0 1 0 0
0 0 0 0 0
0 0 0 1 0
1 1 0 1 1
0 0 0 0 0
Input 2: 起点 = (0, 4)
Input 3: 终点 = (4, 4)
Output: True
二维移动是典型的无向图,对于每点而言,一般存在4个邻接点;对于判断能否到达终点,用BFS或DFS遍历即可,若遍历完整个图,还没有到达终点位置则不可到达终点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| var canReachDest = function (maze, start, destination) { if (maze.length == 0 || maze[0].length == 0) return false; if (start[0] == destination[0] && start[1] == destination[1]) return true; var visited = []; for (var i = 0; i < maze.length; i++) { visited.push(new Array(maze[0].length).fill(false)); } return DFS(maze, visited, start[0], start[1], destination);
};
function DFS(maze, visited, i, j, dest) { if (visited[i][j]) return false; if (i == dest[0] && j == dest[1]) return true; visited[i][j] = true; var dir = [[0, -1], [1, 0], [0, 1], [-1, 0]]; for (var k = 0; k < dir.length; k++) { var newI = i, newJ = j; while (newI + dir[k][0] > -1 && newI + dir[k][0] < maze.length && newJ + dir[k][1] > -1 && newJ + dir[k][1] < maze[0].length && maze[newI + dir[k][0]][newJ + dir[k][1]] != 1) { newI += dir[k][0]; newJ += dir[k][1]; } if (DFS(maze, visited, newI, newJ, dest)) return true;
} return false; }
|