作为一名经历过多次大厂算法面试的开发者,我深知二叉树相关题目在技术面试中的高频出现率。今天我想通过两道LeetCode经典题目(513.找树左下角的值和112.路径总和),分享我在实际刷题和面试中总结的解题思路和编码技巧。这些经验不仅帮助我在面试中脱颖而出,也让我在日常开发中处理树形结构数据时更加得心应手。
这道题要求我们找到二叉树最后一行最左边的值。看似简单的要求背后,其实考察了对二叉树遍历顺序的深入理解。在实际面试中,面试官常常会通过这类问题考察候选人对基础数据结构的掌握程度。
关键点在于:
java复制class Solution {
public int maxdepth = 0;
public int result;
public void traverval(TreeNode root, int depth) {
// 终止条件:到达叶子节点
if(root.left == null && root.right == null) {
if(maxdepth < depth) {
maxdepth = depth;
result = root.val;
}
return;
}
// 优先遍历左子树
if(root.left != null) {
depth++;
traverval(root.left, depth);
depth--;
}
// 再遍历右子树
if(root.right != null) {
depth++;
traverval(root.right, depth);
depth--;
}
}
public int findBottomLeftValue(TreeNode root) {
if(root == null) return 0;
result = root.val;
traverval(root, 0);
return result;
}
}
代码中递归的执行顺序是优先遍历左子节点,再遍历右子节点。这个顺序保证了:
终止条件里的判断逻辑if(maxdepth < depth)实现了:
虽然递归解法简洁,但在实际面试中,面试官可能会要求给出迭代解法。这里分享一个使用队列的BFS实现:
java复制public int findBottomLeftValue(TreeNode root) {
if(root == null) return 0;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int result = 0;
while(!queue.isEmpty()) {
int size = queue.size();
result = queue.peek().val; // 记录每层第一个元素
for(int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if(node.left != null) queue.offer(node.left);
if(node.right != null) queue.offer(node.right);
}
}
return result;
}
这种解法从右到左遍历,最后剩下的就是最左边的节点。在实际编码中,要注意队列的操作顺序和层序遍历的特点。
这道题要求判断二叉树中是否存在从根节点到叶子节点的路径,使得路径上所有节点值相加等于目标和。这在处理文件系统路径、决策树等实际场景中都有应用。
关键点在于:
java复制class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root == null) return false;
int count = root.val;
return traverval(root, count, targetSum);
}
public boolean traverval(TreeNode root, int count, int targetSum) {
// 终止条件:到达叶子节点
if(root.left == null && root.right == null) {
return count == targetSum;
}
// 处理左子树
if(root.left != null) {
count += root.left.val;
if(traverval(root.left, count, targetSum)) return true;
count -= root.left.val;
}
// 处理右子树
if(root.right != null) {
count += root.right.val;
if(traverval(root.right, count, targetSum)) return true;
count -= root.right.val;
}
return false;
}
}
traverval(root, count, targetSum)的作用:
提前返回的优化:
java复制if(traverval(root.left, count, targetSum)) return true;
这种写法可以避免不必要的递归调用,一旦找到符合条件的路径就立即返回,提高效率。
在实际编码和面试中,容易犯的错误包括:
调试技巧:
通过这两道题目,我们可以总结出解决二叉树问题的通用方法:
在技术面试中,仅仅写出正确代码是不够的,还需要清晰地表达思路:
二叉树相关算法在实际开发中的应用场景:
根据我的面试经验,面试官常常会围绕二叉树问题提出以下扩展问题:
如何非递归实现这些算法?
如果树很大,如何优化内存使用?
如何处理动态变化的树结构?
如何扩展到多叉树场景?
根据我个人从算法新手到熟练解题的经验,分享几点学习建议:
对于二叉树专题,建议重点掌握:
最后想说的是,算法能力的提升是一个渐进的过程。我从最初一道简单题要花几小时,到现在能快速解决大部分中等难度问题,靠的是持续不断的练习和总结。希望这些经验对正在准备面试或提升算法能力的你有所帮助。如果在实践过程中遇到任何问题,欢迎交流讨论。