目录
题目一:最大二叉树
题目描述:给定一个不重复的整数数组 nums
。 最大二叉树 可以用下面的算法从 nums
递归地构建
思路分析:(图解分析)
构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树
代码:递归
class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
return construct(nums, 0, nums.length);
}
public TreeNode construct(int[] nums, int leftIndex, int rightIndex) {
if (rightIndex - leftIndex < 1) return null;
// 此时数组内只有一个元素,根节点即为叶子节点
if (rightIndex - leftIndex == 1) return new TreeNode(nums[leftIndex]);
int maxIndex = leftIndex; // 初始化最大值所在位置,0
int maxVal = nums[maxIndex]; // 最大值
for (int i = leftIndex + 1; i < rightIndex; i++) { // 找出数组内最大的元素
if (nums[i] > maxVal) {
maxVal = nums[i];
maxIndex = i;
}
}
TreeNode root = new TreeNode(maxVal);
// 根据maxIndex划分左右子树
root.left = construct(nums, leftIndex, maxIndex);
root.right = construct(nums, maxIndex + 1, rightIndex);
return root;
}
}
题目二:合并二叉树
题目描述:
给你两棵二叉树: root1 和 root2 。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点
思路分析:前、中、后序都可解题,将root1和root2内各节点的数值相加,返回一个新的root
解法一:递归
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if (root1 == null) return root2;
if (root2 == null) return root1;
// 修改了root1的数值和结构
root1.val += root2.val;
root1.left = mergeTrees(root1.left, root2.left);
root1.right = mergeTrees(root1.right, root2.right);
return root1;
}
}
解法二:迭代
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if (root1 == null) return root2;
if (root2 == null) return root1;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root1);
queue.offer(root2);
while (!queue.isEmpty()) {
TreeNode node1 = queue.poll();
TreeNode node2 = queue.poll();
// 此时两个节点一定不为空,val相加
node1.val += node2.val;
// 如果两棵树左节点都不为空,加入队列
if (node1.left != null && node2.left != null) {
queue.offer(node1.left);
queue.offer(node2.left);
}
// 如果两棵树右节点都不为空,加入队列
if (node1.right != null && node2.right != null) {
queue.offer(node1.right);
queue.offer(node2.right);
}
// 若node1的左节点为空,直接赋值
if (node1.left == null && node2.left != null) {
node1.left = node2.left;
}
// 若node2的左节点为空,直接赋值
if (node1.right == null && node2.right != null) {
node1.right = node2.right;
}
}
return root1;
}
}
题目三:二叉搜索树重的搜索
题目描述:
给定二叉搜索树(BST)的根节点 root 和一个整数值 val。你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null
思路分析:利用二叉搜索树节点的有序性
解法一:递归
class Solution {
// 递归,利用二叉搜索树特点
public TreeNode searchBST(TreeNode root, int val) {
if (root == null || root.val == val) return root;
if (val < root.val) {
return searchBST(root.left, val);
} else {
return searchBST(root.right, val);
}
}
}
解法二:迭代
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
while (root != null) {
if (val < root.val) root = root.left;
else if (val > root.val) root = root.right;
else return root;
}
return null;
}
}
题目四:验证二叉搜索树
题目描述:给你一个二叉树的根节点 root
,判断其是否是一个有效的二叉搜索树
思路分析:中序遍历下,输出的二叉搜索树节点的数值是有序序列。
代码:递归
// 利用二叉搜索树中序遍历呈单调递增的特性
class Solution {
long pre = Long.MIN_VALUE; // 用于记录前一个节点的数值,并先赋予一个最小值
public boolean isValidBST(TreeNode root) {
if (root == null) {
return true;
}
// 访问左子树,判断它是否为二叉搜索树
if (!isValidBST(root.left)) {
return false;
}
// 访问当前节点:如果当前节点小于等于中序遍历的前一个节点,说明不满足BST,返回 false;否则继续遍历。
if (root.val <= pre) {
return false;
} else {
// 当前节点的值大于pre时,则更新pre
pre = root.val;
}
// 访问右子树,判断它是否为二叉搜索树
return isValidBST(root.right);
}
}