题目链接:最大二叉树
题目描述:
给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:
创建一个根节点,其值为 nums 中的最大值。
递归地在最大值 左边 的 子数组前缀上 构建左子树。
递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums 构建的 最大二叉树 。
解题思路:
本题解题思路确定递归三部曲即可很好的解题
第一步:确定递归函数的参数和返回值
传入参数:传入需要构建的数组
返回值:返回根节点
第二步:确定终止条件
终止条件:递归到单个节点,也就是叶子节点时返回。
第三步:确定单层递归的逻辑
单层逻辑先找到数组最大值然后赋予根节点
然后根据根节点的下标划分左子树和右子树的数组范围。
代码实现:
class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
TreeNode root = new TreeNode();
if (nums.length == 1) {
root.val = nums[0];
return root;
}
int max = 0;
int maxIndex = 0;
for (int i = 0; i < nums.length; i++) {// 找到最大元素的位置和值
if (nums[i] > max) {
max = nums[i];
maxIndex = i;
}
}
root.val = nums[maxIndex];
// 构建左子树
if (maxIndex > 0) {
int[] left = new int[maxIndex];
for (int i = 0; i < maxIndex; i++) {
left[i] = nums[i];
}
root.left = constructMaximumBinaryTree(left);
}
// 构建右子树
if (maxIndex < nums.length - 1) {
int[] right = new int[nums.length - maxIndex - 1];
int j = maxIndex + 1;
for (int i = 0; i < nums.length - maxIndex - 1; i++) {
right[i] = nums[j++];
}
root.right = constructMaximumBinaryTree(right);
}
return root;
}
}
题目链接:合并二叉树
题目描述:
给你两棵二叉树: root1 和 root2 。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。
解题思路:
递归三部曲:
1.确定递归函数的参数和返回值:
传入参数:两棵树节点
返回值:合并后的根节点
2.确定终止条件:
终止条件为两棵树有一课为空或全为空
返回另一个不为空的;
3.确定单层递归的逻辑:
先将两棵树根节点合并
之后递归左子树和右子树。
迭代法的实现方法为使用层序遍历法一次遍历两个节点,对两个节点进行操作即可。
代码实现:
递归法
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if (root1 == null) {
return root2;
}
if (root2 == null) {
return 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> que = new LinkedList<>();
que.offer(root1);
que.offer(root2);
while (!que.isEmpty()) {
TreeNode node1 = que.poll();
TreeNode node2 = que.poll();
node1.val += node2.val;
//两者都不空则加入队列进行下次循环
if (node1.left != null && node2.left != null) {
que.offer(node1.left);
que.offer(node2.left);
}
if (node1.right != null && node2.right != null) {
que.offer(node1.right);
que.offer(node2.right);
}
//1空2不空则直接将2赋予1
if (node1.left == null && node2.left != null) {
}
if (node1.right == null && node2.right != null) {
node1.right = node2.right;
}
//1不空2空则可以不做操作
}
return root1;
}
}
题目链接:二叉搜索树中的搜索
题目描述:
给定二叉搜索树(BST)的根节点 root 和一个整数值 val。
你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。
解题思路:
本题只要了解二叉搜索树左子树小于根节点,右子树大于根节点,按照这个大小关系进行递归和遍历就会很简单。val大于当前值则递归右子树,小于则递归左子树。迭代法同理。
代码实现:
递归法
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
if(root==null||root.val == val){
return root;
}
TreeNode res = new TreeNode();
if(val>root.val){
res = searchBST(root.right,val);
}
if(val<root.val){
res = searchBST(root.left,val);
}
return res;
}
}
迭代法
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
while(root!=null){
if(val==root.val){
return root;
}
if(val>root.val){
root=root.right;
}else if(val<root.val){
root= root.left;
}
}
return root;
}
}
题目链接:验证二叉搜索树
题目描述:
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
解题思路:
要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。
有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。
所以本题最好使用中序遍历来解答,利用中序遍历判断这个序列是不是递增的即可。
代码实现:
递归法
class Solution {
TreeNode max;//记录当前节点父节点的值
public boolean isValidBST(TreeNode root) {
if (root == null) {
return true;
}
// 左子树
boolean left = isValidBST(root.left);
if (!left) {
return false;
}
// 根节点
if (max != null && root.val <= max.val) {
return false;
}
max = root;
// 右子树
boolean right = isValidBST(root.right);
return right;
}
}
迭代法
class Solution {
public boolean isValidBST(TreeNode root) {
if (root == null) {
return true;
}
Stack<TreeNode> sta = new Stack<>();
TreeNode node = null;
while (root != null || !sta.isEmpty()) {
while (root != null) {//中序遍历先最左下节点
sta.push(root);
root = root.left;
}
// 中
TreeNode pop = sta.pop();
if(node!=null &&pop.val<=node.val){
return false;
}
node = pop;
//右
root= pop.right;
}
return true;
}
}