基础
数组,队列,栈
链表
树与递归
中序遍历
中序遍历首先遍历左子树,然后访问根节点,最后遍历右子树。
三种遍历方式
- 递归
空间复杂度:O(n),时间复杂度:O(n)
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
inorder(root, res);
return res;
}
public void inorder(TreeNode root, List<Integer> res) {
if (root == null) {
return;
}
inorder(root.left, res);
res.add(root.val);
inorder(root.right, res);
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/er-cha-shu-de-zhong-xu-bian-li-by-leetcode-solutio/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- 迭代
方法一递归函数用迭代方式实现,两种方式时等价的。区别在于递归的时候隐式地维护了一个栈,迭代则是显示的将这个栈模拟出来。
空间复杂度:O(n),时间复杂度:O(n)
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
// 栈 先进后出
// 前序遍历,出栈顺序:根左右; 入栈顺序:右左根
// 中序遍历,出栈顺序:左根右; 入栈顺序:右根左
// 后序遍历,出栈顺序:左右根; 入栈顺序:根右左
List<Integer> res = new ArrayList<Integer>();
Deque<TreeNode> stk = new LinkedList<TreeNode>();
while (root != null || !stk.isEmpty()) {
while (root != null) {
stk.push(root);
root = root.left;
}
root = stk.pop();
res.add(root.val);
root = root.right;
}
return res;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/er-cha-shu-de-zhong-xu-bian-li-by-leetcode-solutio/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- Morris中序遍历
空间复杂度:O(1),时间复杂度:O(n)
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
TreeNode predecessor = null;
while (root != null) {
if (root.left != null) {
// predecessor 节点就是当前 root 节点向左走一步,然后一直向右走至无法走为止
predecessor = root.left;
while (predecessor.right != null && predecessor.right != root) {
predecessor = predecessor.right;
}
// 让 predecessor 的右指针指向 root,继续遍历左子树
if (predecessor.right == null) {
predecessor.right = root;
root = root.left;
}
// 说明左子树已经访问完了,我们需要断开链接
else {
res.add(root.val);
predecessor.right = null;
root = root.right;
}
}
// 如果没有左孩子,则直接访问右孩子
else {
res.add(root.val);
root = root.right;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/er-cha-shu-de-zhong-xu-bian-li-by-leetcode-solutio/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
二叉搜索树和平衡二叉树
- 平衡二叉树: 左右子树高度差的绝对值不超过1的树。
- 二叉搜索树: 对于树中的每个节点:
- 若其左子树存在,则其左子树中每个节点的值都不大于该节点;
- 若其右子树存在,则其右子树中每个节点的值都不小于该节点。
二叉搜索树变平衡
通过中序遍历将原来的二叉搜索树转化为一个有序序列,然后对这个有序序列递归建树
class Solution {
List<Integer> inorderSeq = new ArrayList<Integer>();
public TreeNode balanceBST(TreeNode root) {
getInorder(root);
return build(0, inorderSeq.size() - 1);
}
public void getInorder(TreeNode o) {
if (o.left != null) {
getInorder(o.left);
}
inorderSeq.add(o.val);
if (o.right != null) {
getInorder(o.right);
}
}
public TreeNode build(int l, int r) {
int mid = (l + r) >> 1;
TreeNode o = new TreeNode(inorderSeq.get(mid));
if (l <= mid - 1) {
o.left = build(l, mid - 1);
}
if (mid + 1 <= r) {
o.right = build(mid + 1, r);
}
return o;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/balance-a-binary-search-tree/solution/jiang-er-cha-sou-suo-shu-bian-ping-heng-by-leetcod/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
有序数组转二叉搜索树
二叉搜索树的中序遍历是升序遍历;可以推出升序排序的数组是二叉搜索树的中序遍历序列。
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return helper(nums, 0, nums.length - 1);
}
public TreeNode helper(int[] nums, int left, int right) {
if (left > right) {
return null;
}
// 总是选择中间位置左边的数字作为根节点
int mid = (left + right) / 2;
TreeNode root = new TreeNode(nums[mid]);
root.left = helper(nums, left, mid - 1);
root.right = helper(nums, mid + 1, right);
return root;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/solution/jiang-you-xu-shu-zu-zhuan-huan-wei-er-cha-sou-s-33/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
二叉树的递归套路
1)假设以X节点为头,假设可以向X左树和X右树要任何信息
2)在上一步的假设下,讨论以X为头节点的树,得到答案的可能性(最重要)
3)列出所有可能性后,确定到底需要向左树和右树要什么样的信息
4)把左树信息和右树信息求全集,就是任何一棵子树都需要返回的信息S
5)递归函数都返回S,每一棵子树都这么要求
6)写代码,在代码中考虑如何把左树的信息和右树信息整合出整棵树的信息
哈希表
双指针
搜索
深度优先搜索(DFS)
DFS是图算法的一种,是一个针对图和树的遍历算法。
思想:对每一个可能的分支路径深入到不能深入为止,而且每个节点只能访问一次(即没有回头路)。·
- 树搜索(判断两个树是否完全相投,结构,值都相同)
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
} else if (p == null || q == null) {
return false;
} else if (p.val != q.val) {
return false;
} else {
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/same-tree/solution/xiang-tong-de-shu-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- 广度优先搜索