深度优先搜索(DFS)
一、思路
沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。
二、简单应用
1.翻转二叉树
// 基本思路:遍历二叉树,如何遍历到的节点有子节点,将当前节点的左右子节点互换
var invertTree = function(root) {
const dfs = (root) => {
if(root.left || root.right) {
// 交换左右子树
[root.left,root.right] = [root.right,root.left];
}
// 深度优先遍历
if(root.left) dfs(root.left);// 如果有左子节点,遍历左子节点的子节点
if(root.right) dfs(root.right);
}
if(root !== null) dfs(root);
return root;
};
2.岛屿数量
// 基本思路:遍历二维数组,遇到'1'将统计结果加一,并将自身及相邻元素(前后左右)变为'0'直到相邻元素的相邻元素都为'0'
var numIslands = function(grid) {
let res = 0;// 初始化统计结果
let rowLen = grid[0].length;// 列数
let columnLen = grid.length;// 行数
// 遍历数组寻找'1'
for(let i = 0;i < columnLen;i++) {
for(let j = 0;j < rowLen;j++) {
if(grid[i][j] === '1') {
res++;
oneToZero(i,j,grid);
}
}
}
return res;
// 将自身及相邻元素(前后左右)变为'0'
function oneToZero(i,j,grid) {
// 如果到达数组边界或元素值为'0'说明到达岛屿边界,停止遍历
if(i<0 || i>=columnLen || j<0 || j>=rowLen || grid[i][j] ==='0') return;
grid[i][j] = '0';
// 深度优先遍历,如果下层节点有值直接遍历下层而不是兄弟节点
oneToZero(i-1,j,grid);
oneToZero(i+1,j,grid);
oneToZero(i,j+1,grid);
oneToZero(i,j-1,grid);
}
};
3.二叉树中的最大路径和
(1)路径每到一个节点,有 3 种选择:
- 停在当前节点。
- 走到左子节点。
- 走到右子节点
(2)如何计算节点可以为父级提供的最大值
maxValue = root.val + Math.max(0,leftMaxValue,rightMaxValue);
注意:不能同时选择左右节点的值,否则会导致父节点在路径中出现两次
(3)计算最大值
设当前节点为最大和路径的根节点,则
curMaxSum = root.val + leftMaxValue+ leftMaxValue;
FinalMaxSum = Math.max(BeforemaxSum,curMaxSum );
//
var maxPathSum = function(root) {
let maxSum = -Infinity;
const dfs = (root)=>{
if(root === null) return 0;
let left = dfs(root.left);
let right= dfs(root.right);
let innerSum = root.val + left + right;
maxSum = Math.max(maxSum,innerSum);
let outputSum = root.val + Math.max(0,left,right);
return outputSum > 0 ? outputSum : 0;
}
dfs(root);
return maxSum;
};
广度优先搜索
1.翻转二叉树
// 基本思路:遍历二叉树,如何遍历到的节点有子节点,将当前节点的左右子节点互换
var invertTree = function(root) {
if(!root) return null;
let queue = [];
queue[0] = root;
while(queue.length) {
let currNode = queue.shift();
if(currNode === null) continue;
[currNode.left,currNode.right] = [currNode.right,currNode.left];
queue.push(currNode.left,currNode.right);// 将下一层的元素放入数组
}
return root;
};
2.岛屿数量
// 基本思路:遍历二维数组,遇到'1'将统计结果加一,并将自身及相邻元素(前后左右)变为'0'直到相邻元素的相邻元素都为'0'
var numIslands = function(grid) {
let res = 0;
let rowLen = grid[0].length;
let columnLen = grid.length;
for(let i = 0;i < columnLen;i++) {
for(let j = 0;j < rowLen;j++) {
if(grid[i][j