最近发现一个很棒系列,labuladong大神的算法讲解,讲的很不错,开始学习并记录一些笔记吧!
数据结构的存储方式只有两种:数组(顺序存储)和链表(链式存储)。
数组遍历框架
线性迭代结构:
1 | void traverse(int[] arr){ |
++i
和i++
的效率有区别,前者直接返回i+1
的结果,后者会生成一个临时变量,因此性能比前者较弱。
链表遍历框架
兼具迭代和递归:
1 | // 基本的单链表节点 |
二叉树遍历
非线性递归遍历结构:
1 | // 基本的二叉树结点 |
扩展到$n$叉树:
1 | // 基本的n叉树结点 |
求二叉树中最大路径和
LeetCode-124,hard——求二叉树中最大路径和(后序遍历):
给定一个非空二叉树,返回其最大路径和。本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
示例 1:
输入:[1, 2, 3]
1
/ \
2 3输出:6
示例 2:
输入:[-10, 9, 20, null, null, 15, 7]
-10
/ \
9 20
/ \
15 7输出:42
1 | class Solution { |
重建二叉树
LeetCode-105,medium——根据前序遍历序列和中序遍历序列还原一棵二叉树(前序遍历):
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如,给出
前序遍历 preorder = [3, 9, 20, 15, 7]
中序遍历 inorder = [9, 3, 15, 20, 7]
返回如下的二叉树: 3
/ \
9 20
/ \
15 7限制:
0 <= 节点个数 <= 5000
1 | TreeNode buildTree(int[] preoeder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd, Map<Integer, Integer> inMap){ |
恢复一棵 BST
LeetCode-99,hard——根据前序遍历序列和中序遍历序列还原一棵二叉树(中序遍历)
二叉搜索树中的两个节点被错误地交换。请在不改变其结构的情况下,恢复这棵树。
示例 1:
输入:[1, 3, null, null, 2]
1
/
3
\
2输出:[3, 1, null, null, 2]
3
/
1
\
2
示例 2:
输入:[3, 1, 4, null, null, 2]
3
/ \
1 4
/
2输出:[2, 1, 4, null, null, 3]
2
/ \
1 4
/
3
进阶:
使用 O(n) 空间复杂度的解法很容易实现。
你能想出一个只使用常数空间的解决方案吗?
思路
二叉排序树的中序遍历序列是有序的,可以将该序列存放于一个数组。遍历该数组,找到顺序不一致的两个下标i
和j
,将arr[i].val
和arr[j].val
的值互换一下即可。
1 | void traverse(TreeNide* node){ |