最大二叉树
给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:
- 二叉树的根是数组中的最大元素。
- 左子树是通过数组中最大值左边部分构造出的最大二叉树。
- 右子树是通过数组中最大值右边部分构造出的最大二叉树。
通过给定的数组构建最大二叉树,并且输出这个树的根节点。
采用前序遍历 先构造中间节点 然后递归构造左子树和右子树
- 确定递归函数的参数和返回值
参数:存放元素的数组 数组的最左边 数组的最右边
返回值:返回该数组构造的二叉树的头结点 返回类型是指向节点的指针
2.确定终止条件
因为输入的数组大小一定是大于等于1的
所以当递归遍历的时候传入的数组大小为1,说明遍历到叶子节点了
方法:定义一个新节点,并把这个数组的数值赋给新的节点,然后返回这个节点。
3.确定单层递归的逻辑
- 先找到数组中最大的值和对应的下标,最大的值构造根节点,下标用来下一步分割数组。(该题与前两题从中序和后序遍历序列构造二叉树类似)
- 最大值所在的下标左区间构造左子树
- 最大值所在的下标右区间构造右子树
注意:此题用左闭右开型
完整代码如下:
class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
return constructMaximumBinaryTree1(nums, 0, nums.length);
}
public TreeNode constructMaximumBinaryTree1(int[] nums, int leftIndex, int rightIndex) {
if (rightIndex - leftIndex < 1) {// 没有元素了
return null;
}
if (rightIndex - leftIndex == 1) {// 只有一个元素
return new TreeNode(nums[leftIndex]);
}
int maxIndex = leftIndex;// 最大值所在位置
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 = constructMaximumBinaryTree1(nums, leftIndex, maxIndex);
root.right = constructMaximumBinaryTree1(nums, maxIndex + 1, rightIndex);
return root;
}
}
二叉搜索树中的搜索
二叉搜索树的性质决定了其递归遍历和迭代遍历与普通二叉树不同。
递归法
- 确定递归函数的参数和返回值
参数:根节点和要搜索的数值
返回值:以这个搜索数值所在的节点
2.确定终止条件
若root为空或找到数值后,返回root节点
3.确定单层递归的逻辑
因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。
若(val<root.val) 搜索左子树 若(val>root.val) 搜索右子树
因为搜索到目标节点了,就要立即return了,这样才是找到节点就返回(搜索某一条边),如果不加return,就是遍历整棵树了。
迭代法
普通二叉树可用栈来模拟深度遍历 可用队列来模拟广度遍历
而二叉搜索树由于结点的有序性,可以不用辅助栈或队列就可以写出迭代法。
注意:二叉搜索树不需要回溯的过程,因为节点的有序性就帮我们确定了搜索方向。
完整代码如下:
递归法
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.right;
}else if(val<root.val){
root=root.left;
}else return root;
}
return root;
}
}
验证二叉搜索树
思路:中序遍历下,输出的二叉搜索树节点的数值是有序序列。
有了这个特性,验证二叉树就相当于变成了判断一个序列是否是递增的。
递归法
- 确定递归函数参数以及返回值
参数:TreeNode root
返回值:bool型 如果找不到符合的节点就立刻返回
- 确定终止条件
空节点也是二叉搜索树
- 确定单层递归的逻辑
中序遍历,一直更新maxValue
若发现maxValue>=root.val 就返回false 元素相同时也要返回false
迭代法
模拟二叉树中序遍历,只需要稍加改动。
完整代码如下:
递归法
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> stack=new Stack<>();
TreeNode pre=null;
while(root!=null||!stack.isEmpty()){
while(root!=null){
stack.push(root);
root=root.left;
}
TreeNode node =stack.pop();
if(pre!=null && node.val<=pre.val){
return false;
}
pre=node;
root=node.right;
}
return true;
}
}