滴滴面试,本来准备很久的算法题,结果面试没有问到。全是八股文。
很长一段时间,大家都说八股文看看就好,纯当复习。
算法题是重点、项目是重点。
算法题是考察对于编码能力的体现。
项目是对于一些细节技术能力的理解程度。
面试过滴滴的同学,可以在评论区聊聊你们的感受。
今天分享的是一个简单的leetcode题目:二叉树的中序遍历。
94.二叉树的中序遍历:leetcode.cn/problems/bi…
给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
示例 1:
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
提示:
- 树中节点数目在范围
[0, 100]内 -100 <= Node.val <= 100
对于这个问题,我们可以使用递归或迭代的方法来实现。
方法一:递归
中序遍历的顺序是左-根-右。
思路:
- 从根节点开始,首先递归遍历左子树。
- 访问根节点的值。
- 然后递归遍历右子树。
步骤:
- 基础情况处理:如果当前节点为空(
null),直接返回空列表或者继续递归的下一步(不执行任何操作),因为这表示已经到达了叶子节点的下一个位置。 - 递归左子树:对当前节点的左子节点调用递归函数,进行中序遍历。
- 访问当前节点:将当前节点的值添加到结果列表中。
- 递归右子树:对当前节点的右子节点调用递归函数,继续进行中序遍历。
- 在完成以上步骤后,所有节点都按照中序遍历的顺序被访问并添加到了结果列表中。最终返回这个列表。
方法二:迭代
使用栈来模拟递归过程。
思路:
- 创建一个空栈和一个结果列表。
- 初始化一个指针,指向根节点。
- 将指针沿着左子树深入,并将路径上的所有节点推入栈中,直到指针为空。
- 当指针为空时,说明已经到达最左侧节点,此时从栈中弹出一个节点,访问它,并将指针移动到该节点的右子节点上。
- 重复步骤3和4,直到栈为空且指针也为空。
步骤:
- 初始化:创建一个空栈和一个结果列表;声明一个指针变量
current,指向根节点。 - 遍历左子树:只要
current不为空,就将其推入栈中,并将current设置为其左子节点。 - 访问节点:当
current为空,从栈中弹出一个节点,将该节点的值添加到结果列表中,并将current指向该节点的右子节点。 - 重复操作:重复步骤2和3,直到栈为空且
current也为空。 - 返回结果列表。
无论是递归还是迭代方法,核心都在于按照中序遍历的顺序(左-根-右)访问每个节点。递归方法更为直观简洁,而迭代方法则避免了递归可能导致的栈溢出问题,尤其是在处理深度很大的树时更加有效。
Python 代码
递归方法
# 定义二叉树节点
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def inorderTraversal(root):
# 用于存储遍历的结果
res = []
def inorder(node):
if not node:
return
inorder(node.left) # 递归遍历左子树
res.append(node.val) # 访问根节点
inorder(node.right) # 递归遍历右子树
inorder(root)
return res
# 测试代码
if __name__ == "__main__":
# 创建示例二叉树 [1, null, 2, 3]
root = TreeNode(1)
root.right = TreeNode(2)
root.right.left = TreeNode(3)
print(inorderTraversal(root)) # 输出:[1, 3, 2]
迭代方法
def inorderTraversal_iterative(root):
stack, res = [], []
current = root
while current or stack:
# 遍历到最左边的节点
while current:
stack.append(current)
current = current.left
current = stack.pop() # 弹出栈顶元素
res.append(current.val) # 访问节点值
current = current.right # 转向右子树
return res
Java 代码
递归方法
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
// 中序遍历函数
void inorder(TreeNode node) {
if (node == null) return;
inorder(node.left); // 遍历左子树
res.add(node.val); // 访问节点
inorder(node.right); // 遍历右子树
}
inorder(root);
return res;
}
// 主函数用于验证
public static void main(String[] args) {
TreeNode root = new TreeNode(1);
root.right = new TreeNode(2);
root.right.left = new TreeNode(3);
Solution solution = new Solution();
List<Integer> result = solution.inorderTraversal(root);
System.out.println(result); // 输出:[1, 3, 2]
}
}
迭代方法
import java.util.List;
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
public List<Integer> inorderTraversalIterative(TreeNode root) {
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode current = root;
while (current != null || !stack.isEmpty()) {
while (current != null) {
stack.push(current);
current = current.left;
}
current = stack.pop(); // 访问节点
res.add(current.val);
current = current.right; // 转向右子树
}
return res;
}
}
这两种语言的代码分别展示了如何通过递归和迭代的方式进行二叉树的中序遍历。在测试代码部分,通过构造一个简单的二叉树并调用inorderTraversal函数来验证我们的实现是否正确。Java代码中,需要创建Solution类的实例来调用非静态方法进行测试。
最近,我们准备了2000多篇,机器学习和深度学习各方向的论文合集。
是各个方向的核心论文,帮助大家打开思路~