文章目录
- 直接刷题链接直达
- 非递归实现求二叉树的深度
- 非递归从左至右打印一颗二叉树中的所有路径
- 判断平衡二叉树
- 二叉搜索树中第K小的元素
- 二叉树的完全性检验
- 根据前&中序遍历结果重建二叉树
- 二叉树的最近公共祖先
- 二叉树的直径
- 二叉树的遍历
直接刷题链接直达
- 非递归实现求二叉树的深度
- 引入队列,统计当前层次节点数目,逐层遍历
- 二叉树的深度(递归和非递归)
- 102. 二叉树的层次遍历
- 非递归从左至右打印一颗二叉树中的所有路径
- 257. 二叉树的所有路径
- 判断平衡二叉树
- 110. 平衡二叉树
- 寻找二叉搜索树中第一个大于k的节点
- 中序遍历求值
- 类似于 230. 二叉搜索树中第K小的元素
- 二叉树的完全性检验
- 958. 二叉树的完全性检验
- 根据前&中序遍历结果重建二叉树
- 首先找到根节点,再划分左右子树区域,逐层递归找到左右子节点
- 105. 从前序与中序遍历序列构造二叉树
- 实现一个二叉搜索树迭代器,包括
next()
和hasNext()
方法(PayPal)- 173. 二叉搜索树迭代器
- 二叉树的右视图(Shopee)
- 199. 二叉树的右视图
- 给定一个二叉树根节点和指定路径,判断二叉树中是否存在给定指定路径,且要求指定路径最后一个元素为叶节点
- 将一颗二叉搜索树转化成一个排序的双向链表
- 不能创建新结点
- 二叉搜索树与双向链表
- 二叉树的最近公共祖先
- 首先判断当前节点是否为指定结点,是则返回
- 递归当前结点的左右子树
- 如果两边均不为null,表示找到,返回当前结点,均为null则返回null,否则返回对应子节点(left / right)
- 236. 二叉树的最近公共祖先
- Lowest Common Ancestor Binary Tree(各种情况详细举例,推荐)
- 二叉树的中序遍历的下一个结点
- 先判断右子结点不为空,返回右子节点最左边的节点
- 若父节点不为空,上溯到根节点的 “/”即返回
- 二叉树的下一个结点
- 红黑树描述及其复杂度分析(插入/查找)
- 查找、插入、删除时间复杂度 --> O(logN)
- 红黑树 Wiki
- 26 | 红黑树(下):掌握这些技巧,你也可以实现一个红黑树 (红黑树分析)
- 二叉树的直径
- 543. 二叉树的直径
- 二叉树的遍历
- 二叉树的前序遍历 / 二叉树的中序遍历 / 二叉树的后序遍历
非递归实现求二叉树的深度
题目: 给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
递归:
class Solution {
public int maxDepth(TreeNode root) {
if (root == null) return 0;
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return (left > right ? left:right) +1;
}
}
非递归:
引入队列,统计当前层次节点数目,逐层遍历
class Solution {
public int maxDepth(TreeNode root) {
if (root == null) return 0;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
int depth = 0;
while (!q.isEmpty()) {
depth++;
int total = q.size(); // 统计这层的数量=》全部出队列,然后他们的子节点入队
while (total-- > 0) {
TreeNode temp = q.poll();
if (temp.left != null) {
q.offer(temp.left);
}
if (temp.right != null) {
q.offer(temp.right);
}
}
}
return depth;
}
}
非递归从左至右打印一颗二叉树中的所有路径
题目: 给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
递归:
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
treePath(root, "");
return res;
}
List<String> res = new ArrayList<>();
public void treePath(TreeNode root, String path) {
if (root == null) {
return;
}
// 叶子节点
if (root.left == null && root.right == null) {
res.add(path+root.val);
return;
}
treePath(root.left, path+root.val+"->");
treePath(root.right, path+root.val+"->");
}
}
非递归:
class Solution {
// 257. 二叉树的所有路径
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new LinkedList<>();
if (root == null) return res;
// 存放 节点
Stack<TreeNode> nodeStack = new Stack<>();
// 存放 path
Stack<String> pathStack = new Stack<>();
// 根节点 入栈
nodeStack.push(root);
pathStack.push(root.val + "");
while (!nodeStack.isEmpty()) {
TreeNode node = nodeStack.pop();
String path = pathStack.pop();
if (node.left == null && node.right == null) {
res.add(path);
}
if (node.right != null) {
pathStack.push(path + "->" + node.right.val);
nodeStack.push(node.right);
}
if (node.left != null) {
pathStack.push(path + "->" + node.left.val);
nodeStack.push(node.left);
}
}
return res;
}
}
判断平衡二叉树
题目:给定一个二叉树,判断它是否是 平衡二叉树
class Solution {
public boolean isBalanced(TreeNode root) {
if (root == null) return true;
if(Math.abs(findDepth(root.left)-findDepth(root.right)) > 1) return false;
return isBalanced(root.left) && isBalanced(root.right);
}
public int findDepth(TreeNode root) {
if (root == null) return 0;
int left = findDepth(root.left);
int right = findDepth(root.right);
return (left > right ? left:right)+1;
}
}
二叉搜索树中第K小的元素
题目: 给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 小的元素(从 1 开始计数)。
class Solution {
List<Integer> list;
public int kthSmallest(TreeNode root, int k) {
list = new ArrayList<>();
inOrder(root);
return list.get(k-1);
}
public void inOrder(TreeNode root) {
if (root == null) return;
inOrder(root.left);
list.add(root.val);
inOrder(root.right);
}
}
二叉树的完全性检验
题目: 给你一棵二叉树的根节点 root ,请你判断这棵树是否是一棵 完全二叉树 。
对于一个完全二叉树,层序遍历的过程中遇到第一个空节点之后不应该再出现非空节点
class Solution {
public boolean isCompleteTree(TreeNode root) {
if (root == null) return true;
// 层次遍历
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
boolean flag = false; // 开始出现 null 节点
while(!q.isEmpty()) {
TreeNode t = q.poll();
if (flag && t != null) {
return false;
}
if (t == null) {
flag = true;
}else {
q.offer(t.left);
q.offer(t.right);
}
}
return true;
}
}
根据前&中序遍历结果重建二叉树
题目:给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
class Solution {
private HashMap<Integer, Integer> inorderMap; // 存放中序值和索引
private int preorderIndex = 0;// 当前访问的前序的位置
public TreeNode buildTree(int[] preorder, int[] inorder) {
inorderMap = new HashMap<>();
for (int i = 0; i < inorder.length; i++) {
inorderMap.put(inorder[i], i);
}
return createTree(preorder, 0, inorder.length-1);
}
public TreeNode createTree(int[] preorder, int left, int right) {
if (left > right) return null;
int val = preorder[preorderIndex++];
TreeNode root = new TreeNode(val);
root.left = createTree(preorder, left, inorderMap.get(val)-1);
root.right = createTree(preorder, inorderMap.get(val)+1, right);
return root;
}
}
二叉树的最近公共祖先
题目: 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || p == root || q == root) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left != null && right != null) return root;
return left != null ? left:right;
}
}
二叉树的直径
给你一棵二叉树的根节点,返回该树的 直径 。
二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。
两节点之间路径的 长度 由它们之间边数表示。
class Solution {
// 543 二叉树的直径
private int maxDiameter = 0;
public int diameterOfBinaryTree(TreeNode root) {
maxDepth(root); // 在计算深度的过程中更新最大直径
return maxDiameter;
}
// 计算树的最大深度,同时更新最大直径
private int maxDepth(TreeNode node) {
if (node == null) {
return 0;
}
int left = maxDepth(node.left); // 左子树深度
int right = maxDepth(node.right); // 右子树深度
// 更新直径:左子树深度 + 右子树深度
maxDiameter = Math.max(maxDiameter, left + right);
// 返回当前节点的深度
return Math.max(left, right) + 1;
}
}
二叉树的遍历
前序遍历:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
preorder(root);
return ans;
}
List<Integer> ans = new ArrayList<>();
public void preorder(TreeNode root) {
if (root == null) return;
ans.add(root.val);
preorder(root.left);
preorder(root.right);
}
}
中序遍历:
class Solution {
// 92 中序遍历
public List<Integer> inorderTraversal(TreeNode root) {
inorder(root);
return ans;
}
List<Integer> ans = new ArrayList<>();
public void inorder(TreeNode root) {
if (root == null) return;
inorder(root.left);
ans.add(root.val);
inorder(root.right);
}
}
后续遍历:
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
postorder(root);
return ans;
}
List<Integer> ans = new ArrayList<>();
public void postorder(TreeNode root) {
if (root == null) return;
postorder(root.left);
postorder(root.right);
ans.add(root.val);
}
}