Zero title: Algorithm (leetcode, with mind map + all solutions) 300 questions (124) Maximum path sum in binary tree
a topic description
Two solutions overview (mind map)
All three solutions
Interviewer: The topic is almost the same, how is it? Do you have any ideas?
Madman Zhang San: For the binary tree problem, we can give priority to using [recursion] .
Interviewer: Oh? Why is this?
Madman Zhang San: There is a book on biology - "structure and function adapt" , then I think there are similar things in "algorithm", such as "data structure and algorithm adapt" - carefully observe, you will find , the structure of the current root node and its left and right nodes is "isomorphic" , then we will naturally think of using "recursion" .
Interviewer:
Madman Zhang San:
Interviewer (with a serious face):
Narrator: After 4 minutes and 41 seconds, Zhang San wrote the following code in unison.
1 Scenario 1
1) Code:
// 方案1 “就地更新 - 再次遍历法(自己)”。
// 技巧:二叉树的题目应优先考虑使用递归。
// 思路:
// 1)状态初始化:resVal = Number.NEGATIVE_INFINITY (因 要求最大值,故 先置为 最大的负数值 )
// 2)核心1:根据情况,更新 树上各节点的值 。
// 3)核心2:遍历新树,更新最大值 resVal 。
// 4)返回结果 resVal 。
var maxPathSum = function(root) {
// 根据情况,更新 树上各节点的值 。
const updateTree = (root = null) => {
// 1.1)递归出口1
if (!root) {
return;
}
// 1.2)递归出口2
let {left, right, val} = root;
if ((!left) && (!right)) {
return;
}
// 2)递归主体
// 2.1)更新 左子树的值 。
updateTree(left);
// 2.2)更新 右子树的值 。
updateTree(right);
// 2.3)更新 根节点的值 。
// 分3种情况:带上左子树的值 或 带上右子树的值 或 左、右子树值均不带。
root.val = val + Math.max((left?.val || 0), (right?.val || 0), 0);
// 2.4)更新结果值 resVal 。
resVal = Math.max(resVal, val + (left?.val || 0) + (right?.val || 0));
};
// 遍历新树,更新最大值 resVal 。
const getMaxValByNewTree = (root = null) => {
// 1)递归出口
if (!root) {
return;
}
// 2)递归主体
const {left, right, val} = root;
// 2.1)根节点
resVal = Math.max(resVal, val);
// 2.2)左子树
getMaxValByNewTree(left);
// 2.3)右子树
getMaxValByNewTree(right);
};
// 1)状态初始化:resVal = Number.NEGATIVE_INFINITY (因 要求最大值,故 先置为 最大的负数值 )
let resVal = Number.NEGATIVE_INFINITY;
// 2)核心1:根据情况,更新 树上各节点的值 。
updateTree(root);
// 3)核心2:遍历新树,更新最大值 resVal 。
getMaxValByNewTree(root);
// 4)返回结果 resVal 。
return resVal;
};
Madman Zhang San: How is it?
Interviewer: A look of disdain.
Madman Zhang San: Full of confidence.
Interviewer: Take a closer look at your solution, have you traversed it twice? So what did they do in these two traversals? Can we just do 1 pass - ie do a merge of the passes?
Narrator: Facing the interviewer's one-button 3-question ("implying one-button three-link??"), Zhang directly "scared three drops of cold sweat".
Madman Zhang San (his face turned pale, and read the code carefully. Suddenly he realized):
1、确实遍历了2次。
2、分了做了如下工作:
1)updateTree:遍历树,当前节点值从左、右子树的值和0中选出最大值,并加到当前根节点的值上。并 更新结果值 resVal (因为此时的 resVal 有可能是 有当前根节点、当前左、右子树一起组成的路径值之和)。
2)getMaxValByNewTree:更新结果值 resVal(因为此时的 resVal 有可能是在当前根节点取得的)。
3、看起来,updateTree、getMaxValByNewTree中产生的操作可以合并到一起。
Beside: After a while (4 minutes and 11 seconds passed), Zhang San wrote the following code based on scheme 1 and new ideas.
2 Option 2
1) Code:
// 方案2 “官方,递归法。(本质:跟方案1的思路是一致的,只是少了1次树的遍历 —— getMaxValByNewTree)”。
// 参考:
// 1)https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/solution/er-cha-shu-zhong-de-zui-da-lu-jing-he-by-leetcode-/
// 思路:
// 1)状态初始化:resVal = Number.NEGATIVE_INFINITY
// (因 要求最大值,故 先置为 最大的负数值 )。
// 2)核心:遍历新树,更新最大值 resVal 。
// 3)返回结果 resVal 。
var maxPathSum = function(root) {
// 核心:递归处理!
const maxGain = (root = null) => {
// 1)递归出口
if (!root) {
return 0;
}
// 2)递归主体
// 2.1)递归计算左右子节点的最大贡献值
// 只有在最大贡献值大于 0 时,才会选取对应子节点
const leftGain = Math.max(maxGain(root.left), 0),
rightGain = Math.max(maxGain(root.right), 0),
// 节点的最大路径和取决于该节点的值与该节点的左右子节点的最大贡献值
priceNewpath = root.val + leftGain + rightGain;
// 2.2)更新结果值 resVal 。
resVal = Math.max(resVal, priceNewpath);
// 2.3)返回当前根节点的最大贡献值。
return root.val + Math.max(leftGain, rightGain);
}
// 1)状态初始化:resVal = Number.NEGATIVE_INFINITY
// (因 要求最大值,故 先置为 最大的负数值 )。
let resVal = Number.NEGATIVE_INFINITY;
// 2)核心:遍历新树,更新最大值 resVal 。
maxGain(root);
// 3)返回结果 resVal 。
return resVal;
}
Madman Zhang San (after writing the above code, he hurriedly asked the interviewer): This is the best solution, so it is considered to pass the interview, right?
Interviewer: Ruzi can be taught~
Madman Zhang San:
Another offer, and I'm going to be the CEO soon. Should I go to eat Shaxian snacks in the evening? Or Lanzhou Ramen ? Alas, having too many choices is also an annoyance!
Four resource sharing & more
1 Historical Articles - Overview
2 Introduction to bloggers
Code Farmer Sanshao, a blogger dedicated to writing minimalist but complete problem solutions (algorithms ).
Focus on one question, multiple solutions, structured thinking , welcome to brush through LeetCode ~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。