字节美团快手微软面试题——145. 二叉树的后序遍历
145. 二叉树的后序遍历
给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
示例 1:
输入: root = [1,null,2,3]
输出:[3,2,1]
解释:
示例 2:
输入: root = [1,2,3,4,5,null,8,null,null,6,7,9]
输出:[4,6,7,5,2,9,8,3,1]
解释:
示例 3:
输入: root = []
输出: []
示例 4:
输入: root = [1]
输出:[1]
提示:
- 树中节点的数目在范围
[0, 100]内 -100 <= Node.val <= 100
进阶:递归算法很简单,你可以通过迭代算法完成吗?
有返回值无辅助参数的DFS
▼java复制代码class Solution { // 动态规划思路 // 定义:输入一个节点,返回以该节点为根的二叉树的后序遍历结果 public List<Integer> postorderTraversal(TreeNode root) { List<Integer> res = new LinkedList<>(); if (root == null) { return res; } // 后序遍历结果特点:先是左子树,接着是右子树,最后是根节点的值 res.addAll(postorderTraversal(root.left)); res.addAll(postorderTraversal(root.right)); res.add(root.val); return res; } }
无返回值有辅助参数的DFS
▼java复制代码class Solution { public List<Integer> postorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<Integer>(); postorder(root, res); return res; } public void postorder(TreeNode root, List<Integer> res) { if (root == null) { return; } postorder(root.left, res); postorder(root.right, res); res.add(root.val); } }
- 时间复杂度:O(n),其中 n 是二叉搜索树的节点数。每一个节点恰好被遍历一次。
- 空间复杂度:O(n),为递归过程中栈的开销,平均情况下为 O(logn),最坏情况下树呈现链状,为 O(n)。
Morris后序遍历
▼java复制代码class Solution { public List<Integer> postorderTraversal(TreeNode root) { // 创建结果列表,用于存储后序遍历的节点值 List<Integer> result = new ArrayList<>(); if (root == null) { return result; // 如果根节点为空,直接返回空列表 } // currentNode 表示当前遍历的节点,predecessor 表示当前节点的前驱节点 TreeNode currentNode = root, predecessor = null; // 开始遍历树 while (currentNode != null) { predecessor = currentNode.left; // predecessor 指向 currentNode 的左子节点 if (predecessor != null) { // 寻找 currentNode 节点的前驱节点(左子树中的最右节点) while (predecessor.right != null && predecessor.right != currentNode) { predecessor = predecessor.right; } if (predecessor.right == null) { // 如果前驱节点的右指针为空,将其指向 currentNode,构建线索 predecessor.right = currentNode; // 移动 currentNode 到其左子节点,继续遍历 currentNode = currentNode.left; continue; } else { // 如果前驱节点的右指针指向 currentNode,恢复树的原结构 predecessor.right = null; // 将从 currentNode.left 到 currentNode 的路径(全是往右走)添加到结果中,并反转顺序。重点。在示例2中路径是7,5,2,因为后序遍历是4,6,7,5,2 addPath(result, currentNode.left); } } // 如果没有左子树,直接移动到右子节点 currentNode = currentNode.right; } // 最后将根节点到最右节点的路径添加到结果中,并反转顺序 addPath(result, root); return result; // 返回后序遍历的结果 } /** * 将从 node 到路径的最右节点的值添加到结果列表中,并反转顺序。 * @param result 用于存储节点值的列表 * @param node 当前路径的起始节点 */ public void addPath(List<Integer> result, TreeNode node) { List<Integer> temp = new ArrayList<>(); while (node != null) { temp.add(node.val); // 将节点值添加到临时列表 node = node.right; // 移动到右子节点 } // 反转临时列表的顺序,并将其添加到结果中 for (int i = temp.size() - 1; i >= 0; i--) { result.add(temp.get(i)); } } }
- 时间复杂度:O(n),其中 n 是二叉树的节点数。没有左子树的节点只被访问一次,有左子树的节点被访问两次。
- 空间复杂度:O(1)。只操作已经存在的指针(树的空闲指针),因此只需要常数的额外空间。
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
内容推荐
我想问一下大家简历的字体是多少号的呢,是2页还是3页
2
今天面了两家公司,面试时间都比较短直接总结到一起了第一家1. 自我介绍2. 公司两个项目开发中,用到 Codex 或 Claude Code 了吗?3. 具体是用来写什么?用的是最多的哪个?4. Claude Code 用的是什么模型?5. 什么时候开始用的?(精确到具体月份)6. 是官方账号还是中转站?7. 当时开发一天用多少钱?8. 平时用到什么 Skill 或 MCP 吗?9. Claude
5
找实习从7月22号开始投,现在也总算是有offer了
5
怎么会有笨蛋从一月到现在,背了7个月的面试题,还啥都不会呢,到底背哪里去了,该怎么办
3
【入职求助贴】萌新刚入职某大厂做后端开发,目前还在试用期。最近遇到一个棘手的问题,想向大家求助一下。入职不久,leader 给我派了一个任务。跟我说是0.5天就可以解决,我刚毕业入职,做了一个星期没有做出来。实现一个收集定时成功任务的案例。听起来好像不复杂,但我自己摸索着做了一整个星期,到现在还没达到预期效果。这一周我基本是“边学边做”的状态,遇到卡点也会每天主动找 leader 沟通进度和疑问。
2
作者分享
请问大家,本站post页面(例如https://www.codefather.cn/post/1936081812592168962)的粘性侧边栏是怎么实现的?是不是需要改BasicLayout的css?不知道开发大佬是否方便透露。
AI告诉我需要这样修改BasicLayout的index.css和index.tsx:
```css
#basicLayout .ant-pro-layout-content {
overflow: visible !important;
}
```
```
<ProLayout
layout="top"
location={{
pathname,
}}
fixedHeader={true}
>
<div>
<Row gutter={[12, 0]} style={{ alignItems: "flex-start" }}>
<Col xs={24} sm={24} md={16}>
{children}
</Col>
<Col xs={0} sm={0} md={8}>
<Sidebar />
</Col>
</Row>
</div>
</ProLayout>
```
Sidebar如下,使用了StickyBox:
```
'use client';
import React from 'react';
import StickyBox from 'react-sticky-box';
const Sidebar: React.FC = () => {
return (
<StickyBox>
<div>
....
</div>
</StickyBox>
);
};
export default Sidebar;
```
但是无效……
2
请问大家有没有好用的云IDE,就是不用自己在本地搭环境,在浏览器中开发的那种。
3
请问大家,以面试鸭项目为例,把导航栏设置为固定位置(fixHeader={true})后,怎么实现侧边栏的粘顶粘底效果?就是侧边栏滚动到自己的底部就停止,不会跟着主内容区一直滚动。
1
gap太久了,打算去华为od了……
2
请问下大家,boss直聘、内推、官网投递都会有面评是吗?(大厂)
1
