代码随想录算法训练营第十四天| 二叉树相关递归遍历以及迭代遍历
1.代码随想录算法训练营第二天| 977.有序数组的平方、 209.长度最小的子数组、 59.螺旋矩阵II2.代码随想录算法训练营第三天| 203. 移除链表元素 707.设计链表 206.反转链表3.代码随想录算法训练营第四天| 24. 两两交换链表中的节点 19.删除链表的倒数第N个节点 面试题 02.07. 链表相交 142. 环形链表 II4.代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素。5.代码随想录算法训练营第六天| 242. 有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和6.代码随想录算法训练营第七天| 454. 四数相加 II 383. 赎金信 15. 三数之和 18. 四数之和7.代码随想录算法训练营第九天| 28. 实现 strStr() 和讲讲KMP8.代码随想录算法训练营第十天| 232. 用栈实现队列 225. 用队列实现栈9.代码随想录算法训练营第十一天| 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值10.代码随想录算法训练营第十三天| 239. 滑动窗口最大值 347. 前 K 个高频元素
11.代码随想录算法训练营第十四天| 二叉树相关递归遍历以及迭代遍历
12.代码随想录算法训练营第十五天| 226. 翻转二叉树 101. 对称二叉树13.代码随想录算法训练营第十六天| 104. 二叉树的最大深度 111. 二叉树的最小深度 222. 完全二叉树的节点个数14.代码随想录算法训练营第十七天| 110. 平衡二叉树 257. 二叉树的所有路径 404. 左叶子之和15.代码随想录算法训练营第十八天| 513. 找树左下角的值 112. 路径总和 113. 路径总和 II 106. 从中序与后序遍历序列构造二叉树 105. 从前序与中序遍历序列构造二叉树16.代码随想录算法训练营第二十一天,二十二,二十三| 530. 二叉搜索树的最小绝对差 501. 二叉搜索树中的众数 236. 二叉树的最近公共祖先 235. 二叉搜索树的最近公共祖先 701. 二叉搜索树中的插入操作 450. 删除二叉搜索树中的节点17.代码随想录算法训练营第二十四天 二十五 | 回溯的理论基础,77. 组合 216. 组合总和 III 17. 电话号码的字母组合18.代码随想录 | 图论 797. 所有可能的路径(dfs) ,200. 岛屿数量 (dfs)200. 岛屿数量 (bfs) ,并查集,1971. 寻找图中是否存在路径二叉树的递归遍历
递归三要素:确定递归函数的参数和返回值,确定终止条件,确定单层递归的逻辑
144. 二叉树的前序遍历
https://leetcode.cn/problems/binary-tree-preorder-traversal/description/
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
preorder(root,list);
return list;
}
public void preorder(TreeNode root , List<Integer> list){
if (root == null) return;
list.add(root.val);
preorder(root.left,list);
preorder(root.right,list);
}
前序迭代
public List<Integer> preorderTraversal(TreeNode root) {
Deque<TreeNode> deque = new ArrayDeque<>();
List<Integer> list = new ArrayList<>();
if (root != null) deque.addFirst(root);
while (!deque.isEmpty()){
TreeNode node = deque.pollFirst();
list.add(node.val);
if (node.right != null) deque.addFirst(node.right);
if (node.left != null) deque.addFirst(node.left);
}
return list;
}
总结:入栈顺序:中右左,出战顺序就是中左右
后序迭代
public List<Integer> postorderTraversal(TreeNode root) {
Deque<TreeNode> deque = new LinkedList<>();
List<Integer> list = new ArrayList<>();
if (root != null) deque.addFirst(root);
while (!deque.isEmpty()){
TreeNode node = deque.pollFirst();
list.add(node.val);
if (node.left != null) deque.addFirst(node.left);
if (node.right != null) deque.addFirst(node.right);
}
Collections.reverse(list);
return list;
}
总结:入栈顺序:中左右,出栈顺序:中右左,再list翻转,就是左右中了。
中序迭代
public List<Integer> inorderTraversal(TreeNode root) {
Deque<TreeNode> deque = new LinkedList<>();
List<Integer> list = new ArrayList<>();
TreeNode p = root;
while (p != null || !deque.isEmpty()){
if (p != null){
deque.addFirst(p);
p = p.left;
}else {
p = deque.pollFirst();
list.add(p.val);
p = p.right;
}
}
return list;
}
总结:中序迭代和前序后序的不一样,中序迭代核心思想:让p一路向左,当p没有左了,栈弹出并p指向他,加入list,p再向右,这样就完成了左中右的操作,注意中序迭代要放在一个while循环里,因为每次想加入list的前提就是当前的p节点没有左孩子。
层序遍历非递归
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> resList = new ArrayList<>();
Deque<TreeNode> deque = new LinkedList<>();
if (root == null) return resList;
deque.offer(root);
while (!deque.isEmpty()){
List<Integer> list = new ArrayList<>();
int size = deque.size();
for (int i = 0; i < size; i++) {
TreeNode node = deque.poll();
list.add(node.val);
if (node.left != null) deque.offer(node.left);
if (node.right != null) deque.offer(node.right);
}
resList.add(list);
}
return resList;
}
总结:注意for循环中如果写i < deque.size()会发生错误,因为每次for循环deque的长度都在变。
层序遍历递归
//todo
合集:
算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?