东哥带你刷二叉树(纲领篇) :: labuladong的算法小抄 #1007
Replies: 95 comments 18 replies
-
学到不少 NICE |
Beta Was this translation helpful? Give feedback.
-
你只需要思考每一个节点应该做什么,其他的不用你管,抛给二叉树遍历框架,递归会对所有节点做相同的操作。 遇到一道二叉树的题目时的通用思考过程是:是否可以通过遍历一遍二叉树得到答案?如果不能的话,是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案? 如果需要设计到子树信息, 建议使用后续遍历. |
Beta Was this translation helpful? Give feedback.
-
@Asber777 这个总结很好 |
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.
-
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.
-
我觉得树深度那道题的遍历思路和分解问题思路,只不过是从根到叶子与叶子到根两个递推的方向罢了,本质是一样的,遍历和分解问题没有什么区别。 |
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.
-
文章链接点这里:东哥带你刷二叉树(纲领篇)
评论礼仪 见这里,违者直接拉黑。
Beta Was this translation helpful? Give feedback.
All reactions