树问题总结
树问题总结
总结Leetcode上刷的树问题
二叉树的中序遍历
题目描述
给定一个二叉树,返回它的中序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,3,2]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
TreeNode p = root;
while (p!=null|| !stack.isEmpty()) {
while (p!=null) {
stack.push(p);
p=p.left;
}
if (!stack.isEmpty()) {
p = stack.pop();
res.add(p.val);
p=p.right;
}
}
return res;
}
}
不同的二叉搜索树
题目描述
给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?
示例:
输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-binary-search-trees
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
动态规划思想
class Solution {
public int numTrees(int n) {
int[] G = new int[n + 1];
G[0] = 1;
G[1] = 1;
//第一层循环表示长度
for (int i = 2; i <= n; ++i) {
//第二层循环表示 根从那个开始
for (int j = 1; j <= i; ++j) {
G[i] += G[j - 1] * G[i - j];
}
}
return G[n];
}
}
不同的二叉搜索树II
题目描述
给定一个整数 n,生成所有由 1 ... n 为节点所组成的 二叉搜索树 。
示例:
输入:3
输出:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
解释:
以上的输出对应以下 5 种不同结构的二叉搜索树:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-binary-search-trees-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<TreeNode> generateTrees(int n) {
if (n == 0) {
return new LinkedList<TreeNode>();
}
return generate_trees(1, n);
}
public LinkedList<TreeNode> generate_trees(int start, int end) {
LinkedList<TreeNode> all_trees = new LinkedList<TreeNode>();
if (start > end) {
all_trees.add(null);
return all_trees;
}
// 选择一个作为根
for (int i = start; i <= end; i++) {
//可能的左子树
LinkedList<TreeNode> left_trees = generate_trees(start, i - 1);
// 可能的右子树
LinkedList<TreeNode> right_trees = generate_trees(i + 1, end);
// 两者联系起来
for (TreeNode l : left_trees) {
for (TreeNode r : right_trees) {
TreeNode current_tree = new TreeNode(i);
current_tree.left = l;
current_tree.right = r;
all_trees.add(current_tree);
}
}
}
return all_trees;
}
}
验证二叉搜索树
题目描述
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:
2
/ \
1 3
输出: true
示例 2:
输入:
5
/ \
1 4
/ \
3 6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
根节点的值为 5 ,但是其右子节点值为 4 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/validate-binary-search-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
//这个pre非常巧妙
long pre = Long.MIN_VALUE;
public boolean isValidBST(TreeNode root) {
if (root==null) {
return true;
}
if(!isValidBST(root.left)){
return false;
};
if (root.val <= pre) {
return false;
}
pre = root.val;
return isValidBST(root.right);
}
}
相同的树
题目描述
给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入: 1 1
/ \ / \
2 3 2 3
[1,2,3], [1,2,3]
输出: true
示例 2:
输入: 1 1
/ \
2 2
[1,2], [1,null,2]
输出: false
示例 3:
输入: 1 1
/ \ / \
2 1 1 2
[1,2,1], [1,1,2]
输出: false
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/same-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p==null && q==null) return true;
if(p==null || q==null)return false;
return p.val==q.val && isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
}
}
对称二叉树
题目描述
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/symmetric-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root==null) {
return true;
}
return IsSymmetric(root.left,root.right);
}
boolean IsSymmetric(TreeNode pRoot1,TreeNode pRoot2){
if (pRoot1==null&&pRoot2==null) {
return true;
}
if (pRoot1==null||pRoot2==null) {
return false;
}
return pRoot1.val==pRoot2.val && IsSymmetric(pRoot1.left,pRoot2.right) && IsSymmetric(pRoot1.right,pRoot2.left) ;
}
}
二叉树的层次遍历
题目描述
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:[3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root==null) {
return res;
}
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
int nextLevel = 0;
int toBePrinted = 1;
ArrayList<Integer> temp = new ArrayList<>();
while (!queue.isEmpty()) {
TreeNode p =queue.pop();
temp.add(p.val);
toBePrinted--;
if (p.left!=null) {
queue.add(p.left);
nextLevel++;
}
if (p.right!=null) {
queue.add(p.right);
nextLevel++;
}
//说明这一层打印完毕
if (toBePrinted==0) {
res.add(temp);
temp =new ArrayList<>();
toBePrinted = nextLevel;
nextLevel = 0;
}
}
return res;
}
}
二叉树的锯齿形层次遍历
题目描述
给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
例如:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回锯齿形层次遍历如下:
[
[3],
[20,9],
[15,7]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
使用双端队列
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
if (root == null) {
return new ArrayList<List<Integer>>();
}
List<List<Integer>> results = new ArrayList<List<Integer>>();
// add the root element with a delimiter to kick off the BFS loop
LinkedList<TreeNode> node_queue = new LinkedList<TreeNode>();
node_queue.addLast(root);
//把null作为结束
node_queue.addLast(null);
LinkedList<Integer> level_list = new LinkedList<Integer>();
boolean is_order_left = true;
while (node_queue.size() > 0) {
TreeNode curr_node = node_queue.pollFirst();
if (curr_node != null) {
if (is_order_left)
level_list.addLast(curr_node.val);
else
level_list.addFirst(curr_node.val);
if (curr_node.left != null)
node_queue.addLast(curr_node.left);
if (curr_node.right != null)
node_queue.addLast(curr_node.right);
} else {
// we finish the scan of one level
results.add(level_list);
level_list = new LinkedList<Integer>();
// prepare for the next level
if (node_queue.size() > 0)
node_queue.addLast(null);
is_order_left = !is_order_left;
}
}
return results;
}
}
使用深度优先遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
protected void DFS(TreeNode node, int level, List<List<Integer>> results) {
if (level >= results.size()) {
LinkedList<Integer> newLevel = new LinkedList<Integer>();
newLevel.add(node.val);
results.add(newLevel);
} else {
if (level % 2 == 0)
results.get(level).add(node.val);
else
results.get(level).add(0, node.val);
}
if (node.left != null) DFS(node.left, level + 1, results);
if (node.right != null) DFS(node.right, level + 1, results);
}
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
if (root == null) {
return new ArrayList<List<Integer>>();
}
List<List<Integer>> results = new ArrayList<List<Integer>>();
DFS(root, 0, results);
return results;
}
}
二叉树的最大深度
题目描述
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最大深度 3 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if (root==null) {
return 0;
}
TreeNode left = root.left;
TreeNode right = root.right;
return Math.max(maxDepth(left), maxDepth(right))+1 ;
}
}
从前序与中序遍历序列构造二叉树
题目描述
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int[] preorder;
int[] inorder;
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder==null || preorder.length==0) {
return null;
}
this.preorder = preorder;
this.inorder = inorder;
return BuildTree(0,preorder.length-1,0,inorder.length-1);
}
//发现其实这些 end没啥大用,就是为了好理解
public TreeNode BuildTree(int pStart,int pEnd, int inStart,int inEnd){
//第一个是根节点
TreeNode root = new TreeNode(preorder[pStart]);
if (pStart==pEnd) {
return root;
}
int i=inStart;
//从中序遍历中找出根节点,将其分开
for (; i <=inEnd; i++) {
if (preorder[pStart] == inorder[i]) {
break;
}
}
int len = i-inStart;
if (pStart+1<=pStart+len)
root.left = BuildTree(pStart+1,pStart+len,inStart,i-1);
if (pStart+len+1<=pEnd)
root.right = BuildTree(pStart+len+1,pEnd,i+1,inEnd);
return root;
}
}
从中序与后序遍历序列构造二叉树
题目描述
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int[] postorder;
int[] inorder;
public TreeNode buildTree(int[] inorder, int[] postorder) {
if (postorder==null || postorder.length==0) {
return null;
}
this.postorder = postorder;
this.inorder = inorder;
return BuildTree(0,postorder.length-1,0,inorder.length-1);
}
public TreeNode BuildTree(int pStart,int pEnd, int inStart,int inEnd){
//最后一个是根节点
TreeNode root = new TreeNode(postorder[pEnd]);
if (pStart==pEnd) {
return root;
}
int i=inStart;
//从中序遍历中找出根节点,将其分开
for (; i <=inEnd; i++) {
if (postorder[pEnd] == inorder[i]) {
break;
}
}
int len = i-inStart;
if (pStart<=pStart+len-1)
root.left = BuildTree(pStart,pStart+len-1,inStart,i-1);
if (pStart+len<=pEnd-1)
root.right = BuildTree(pStart+len,pEnd-1,i+1,inEnd);
return root;
}
}
将有序数组转换为二叉搜索树
题目描述
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定有序数组: [-10,-3,0,5,9],
一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int[] nums;
public TreeNode sortedArrayToBST(int[] nums) {
if (nums==null||nums.length==0) {
return null;
}
this.nums=nums;
return creatTree(0, nums.length-1);
}
TreeNode creatTree(int start,int end){
if (start>end) {
return null;
}
int mid = (start+end)/2;
TreeNode root = new TreeNode(nums[mid]);
if (start!=end) {
root.left = creatTree(start,mid-1);
root.right = creatTree(mid+1,end);
}
return root;
}
}
平衡二叉树
题目描述
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
返回 true 。
示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
1
/ \
2 2
/ \
3 3
/ \
4 4
返回 false 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/balanced-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
return IsBalance(root)!=-1;
}
private int IsBalance(TreeNode root){
if(root==null)return 0;
int left = IsBalance(root.left);
// -1代表不平衡
if (left==-1) {
return -1;
}
int right = IsBalance(root.right);
if (right==-1) {
return -1;
}
return Math.abs(left - right) > 1 ? -1 : 1 + Math.max(left, right);
}
}
二叉树的最小深度
题目描述
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最小深度 2.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-depth-of-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int minDepth(TreeNode root) {
if (root==null) {
return 0;
}
//说明是叶子节点
if (root.left==null && root.right==null) {
return 1;
}
int left = root.left==null? Integer.MAX_VALUE : minDepth(root.left);
int right = root.right==null? Integer.MAX_VALUE : minDepth(root.right);
return Math.min(left, right)+1;
}
}

浙公网安备 33010602011771号