东哥带你刷二叉树(纲领篇) :: labuladong的算法小抄 #1007
Replies: 95 comments 18 replies
-
牛蛙牛蛙占个楼 |
Beta Was this translation helpful? Give feedback.
-
学到不少 NICE |
Beta Was this translation helpful? Give feedback.
-
你只需要思考每一个节点应该做什么,其他的不用你管,抛给二叉树遍历框架,递归会对所有节点做相同的操作。 遇到一道二叉树的题目时的通用思考过程是:是否可以通过遍历一遍二叉树得到答案?如果不能的话,是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案? 如果需要设计到子树信息, 建议使用后续遍历. |
Beta Was this translation helpful? Give feedback.
-
@Asber777 这个总结很好 |
Beta Was this translation helpful? Give feedback.
-
666 |
Beta Was this translation helpful? Give feedback.
-
感觉搜索二叉树深度第一个解法,不能用全局变量,要通过指针来传递res,depth |
Beta Was this translation helpful? Give feedback.
-
刷了一些算法吧,刷二叉树类问题确实是承前启后。遍历解法,深一步就是回溯思想。分解子问题解法,深一步就是动态规划。 |
Beta Was this translation helpful? Give feedback.
-
js 版二叉树直径: var diameterOfBinaryTree = function(root) {
let maxDiameter = 0;
// 对每个节点计算直径,求最大直径
maxDepth(root);
return maxDiameter;
// 计算二叉树的最大深度
function maxDepth(root) {
if (root == null) {
return 0;
}
const leftMax = maxDepth(root.left);
const rightMax = maxDepth(root.right);
// 后序位置顺便计算最大直径
const myDiameter = leftMax + rightMax;
maxDiameter = Math.max(maxDiameter, myDiameter);
return Math.max(leftMax, rightMax) + 1;
}
}; |
Beta Was this translation helpful? Give feedback.
-
二叉树的简单 js 实现,可以用来调试代码: class TreeNode {
constructor(value) {
this.val = value;
this.left = null;
this.right = null;
}
insert(values) {
const queue = [this];
let i = 0;
while (queue.length > 0) {
let current = queue.shift();
for (let side of ["left", "right"]) {
if (!current[side]) {
if (values[i] !== null) {
current[side] = new TreeNode(values[i]);
}
i++;
if (i >= values.length) return this;
}
if (current[side]) queue.push(current[side]);
}
}
return this;
}
}
const tree = new TreeNode(15);
tree.insert([1, 2, 3, 4, 3, 8, 7, 5, 10, 12, 11, null, null, null]); |
Beta Was this translation helpful? Give feedback.
-
js 二叉树分治前序遍历 function preorderTraverse(root) {
const res = [];
if (root == null) {
return res;
}
// 前序遍历的结果,root.val 在第一个
res.push(root.val);
// 利用函数定义,后面接着左子树的前序遍历结果
res.push(...preorderTraverse(root.left));
// 利用函数定义,最后接着右子树的前序遍历结果
res.push(...preorderTraverse(root.right));
return res;
} |
Beta Was this translation helpful? Give feedback.
-
牛逼 |
Beta Was this translation helpful? Give feedback.
-
坚持学习! |
Beta Was this translation helpful? Give feedback.
-
515 的题其实利用层序遍历有一种更通用的模板: var largestValues = function(root) {
const level = []
const traverse = (root, depth) => {
if(!root) return
if(!level[depth]) level[depth] = []
traverse(root.left, depth+1)
level[depth].push(root.val)
traverse(root.right, depth+1)
}
traverse(root, 0)
const ans = level.map(arr => Math.max.apply(null, arr))
return ans
}; |
Beta Was this translation helpful? Give feedback.
-
求二叉树深度那里还是不太理解为什么在离开结点之前depth要自减一次 |
Beta Was this translation helpful? Give feedback.
-
啊!突然懂了,左孩子已经执行了一次depth++,在离开结点之前,右孩子也进行了depth++,该层的depth加了两次,所以离开前要让depth自减一次以维护。 |
Beta Was this translation helpful? Give feedback.
-
你好,既然你说了所有算法都是枚举,那为了方便理解,是不是应该从枚举解法出发,一步一步优化到最优算法,这样讲解是不是更好理解些,而不是上来就给最优解法,大部分最优解法如果没有经过专业训练是想不起来的。 |
Beta Was this translation helpful? Give feedback.
-
二叉树的层次遍历不属于递归吧?? |
Beta Was this translation helpful? Give feedback.
-
感觉没有代码随想录说的清楚 |
Beta Was this translation helpful? Give feedback.
-
感谢博主,学到了很多,但看完并非能够砍瓜切菜,博文在行文上自认为存在一些跳跃性,导致还是存在一些疑惑。不论如何,感谢。 |
Beta Was this translation helpful? Give feedback.
-
104 遍历思路的Python代码好像有点问题,说是全局变量depth没有定义。 在stackoverflow上查了,说是在函数内部变量的前面要加个'global'。楼主的gpt代码也是这么做的呀,但还是报错了。 有人知道是leetcode运行的问题还是语法不规范吗? 谢谢🙏
|
Beta Was this translation helpful? Give feedback.
-
请问东哥用的画图工具是什么呀? |
Beta Was this translation helpful? Give feedback.
-
hhy必进大厂 |
Beta Was this translation helpful? Give feedback.
-
我觉得树深度那道题的遍历思路和分解问题思路,只不过是从根到叶子与叶子到根两个递推的方向罢了,本质是一样的,遍历和分解问题没有什么区别。 |
Beta Was this translation helpful? Give feedback.
-
横向遍历求每层的最大值, 就是宽度优先遍历,非递归版: public List<Integer> traverseMaxLevel(TreeNode root) {
List<Integer> maxLevelValRes = new LinkedList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int sz = queue.size();
List<Integer> levelValues = new ArrayList<>(sz);
for (int i = 0; i < sz; i++) {
TreeNode node = queue.poll();
levelValues.add(node.val);
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
maxLevelValRes.add(levelValues.stream().max((a, b) -> {
return a - b;
}).get());
}
return maxLevelValRes;
} |
Beta Was this translation helpful? Give feedback.
-
树的视角看backtrack的cpp修改: void backtrack(int[] nums) {
} |
Beta Was this translation helpful? Give feedback.
-
打卡,前序中序后序就好像生命周期的钩子函数,判定不同的条件可以千变万化,但实际上还是同一套框架 |
Beta Was this translation helpful? Give feedback.
-
总感觉回溯和DFS是一个东西,写在for里面和for外面差不多。但根节点的处理可能有差异 |
Beta Was this translation helpful? Give feedback.
-
104二叉树的最大深度中golang的代码有问题,使用了全局变量 res 和 depth,在连续调用 maxDepth 函数时可能会出现问题。这是因为 res 和 depth 的值在两次函数调用之间没有被重置,导致它们保留了上一次函数调用的状态。
|
Beta Was this translation helpful? Give feedback.
-
关于文章结尾“优秀读者的递归进行层序遍历方法”多说两句。原文中的方法使用C++的queue来pop旧层push进新层,相当于C数组中结尾添加然后移动标志(c数组做circular buffer可以近似queue的效果)。结尾的方法是保留旧的queue添加新的queue,类似于C使用临时Node数组记录新层(可以用memcpy覆盖旧数组来节约空间)。 绕来绕去,关注点似乎跑到了如何用C模拟C++ queue上 |
Beta Was this translation helpful? Give feedback.
-
“如果把根节点看做第 1 层,如何打印出每一个节点所在的层数?” 试了下,把和res有关的代码去掉就成。 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
文章链接点这里:东哥带你刷二叉树(纲领篇)
评论礼仪 见这里,违者直接拉黑。
Beta Was this translation helpful? Give feedback.
All reactions