代码随想录算法训练营第二十天|654.最大二叉树|617.合并二叉树|700.二叉搜索树中的搜索|98.验证二叉搜索树

LeetCode654.最大二叉树

        基本思路:本题采用递归,分为三个步骤:

        (1)确定递归函数的参数和返回值:参数传入的是存放元素的数组,返回该数组构造的二叉树的头结点,返回类型是指向节点的指针。

        (2)确定终止条件:题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。那么应该定义一个新的节点,并把这个数组的数值赋给新的节点,然后返回这个节点。 这表示一个数组大小是1的时候,构造了一个新的节点,并返回。

        (3)确定单层的递归逻辑:分为三个步骤

                1. 先要找到数组中最大的值和对应的下标, 最大的值构造根节点,下标用来下一步分割数组。

                2.最大值所在的下标左区间 构造左子树,这里要判断maxValueIndex > 0,因为要保证左区间至少有一个数值。

                3.最大值所在的下标右区间 构造右子树,判断maxValueIndex < (nums.size() - 1),确保右区间至少有一个数值。

Java代码如下:

    //LeetCode 654 最大二叉树
    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);
    	root.left = constructMaximumBinaryTree1(nums,leftIndex,maxIndex);
    	root.right = constructMaximumBinaryTree1(nums,maxIndex + 1,rightIndex);
    	return root;
    }

LeetCode617.合并二叉树

(1)递归

        基本思路:递归的三个步骤:

        1,确定递归函数的参数和返回值:首先要合入两个二叉树,那么参数至少是要传入两个二叉树的根节点,返回值就是合并之后二叉树的根节点。

        2,确定终止条件:因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL)。反过来如果t2 == NULL,那么两个数合并就是t1(如果t1也为NULL也无所谓,合并之后就是NULL)。

        3,确定单层递归的逻辑:单层递归的逻辑就比较好写了,这里我们重复利用一下t1这个树,t1就是合并之后树的根节点(就是修改了原来树的结构)。那么单层递归中,就要把两棵树的元素加到一起。接下来t1 的左子树是:合并 t1左子树 t2左子树之后的左子树。t1 的右子树:是 合并 t1右子树 t2右子树之后的右子树。最终t1就是合并之后的根节点。

Java代码如下:

    //LeetCode 617 合并二叉树
    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;
    }

(2)迭代

        基本思路:使用队列,模拟的层序遍历

Java代码如下:

    //LeetCode 617 合并二叉树 迭代
    public TreeNode mergeTrees_1(TreeNode root1, TreeNode root2) {
    	if(root1 == null) 
    	{
    		return root2;
    	}
    	if(root2 == null) 
    	{
    		return root1;
    	}
    	Deque<TreeNode> stack = new ArrayDeque<TreeNode>();
    	stack.push(root2);
    	stack.push(root1);
    	while(!stack.isEmpty()) 
    	{
    		TreeNode node1 = stack.pop();
    		TreeNode node2 = stack.pop();
    		node1.val += node2.val;
    		if(node1.right != null && node2.right != null) 
    		{
    			stack.push(node2.right);
    			stack.push(node1.right);
    		}
    		else 
    		{
    			if(node1.right == null) 
    			{
    				node1.right = node2.right;
    			}
    		}
    		if(node1.left != null && node2.left != null) 
    		{
    			stack.push(node2.left);
    			stack.push(node1.left);
    		}
    		else
    		{
    			if(node1.left == null) 
    			{
    				node1.left = node2.left;
    			}
    		}
    	}
    	
    	return root1;
    }

LeetCode700.二叉搜索树中的搜索

(1)递归

        基本思路:递归的三个步骤:

        1,确定递归函数的参数和返回值:递归函数的参数传入的就是根节点和要搜索的数值,返回的就是以这个搜索数值所在的节点。

        2,确定终止条件:如果root为空,或者找到这个数值了,就返回root节点。

        3,确定单层的递归逻辑:看看二叉搜索树的单层递归逻辑有何不同。因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。如果root->val > val,搜索左子树,如果root->val < val,就搜索右子树,最后如果都没有搜索到,就返回NULL。

Java代码如下:

    //LeetCode 700 二叉搜索树中的搜索 递归
    public TreeNode searchBST(TreeNode root, int val) {
    	if(root == null || root.val == val) 
    	{
    		return root;
    	}
    	if(root.val > val) 
    	{
    		return searchBST(root.left,val);
    	}
    	else 
    	{
    		return searchBST(root.right,val);
    	}
    }

 

(2)迭代

        基本思路;一提到二叉树遍历的迭代法,可能立刻想起使用栈来模拟深度遍历,使用队列来模拟广度遍历。对于二叉搜索树可就不一样了,因为二叉搜索树的特殊性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法。对于一般二叉树,递归过程中还有回溯的过程,例如走一个左方向的分支走到头了,那么要调头,在走右分支。而对于二叉搜索树,不需要回溯的过程,因为节点的有序性就帮我们确定了搜索的方向。

Java代码如下:

    //LeetCode 700 二叉搜索树中的搜索 迭代
    public TreeNode searchBST_1(TreeNode root, int val) {
    	while(root != null) 
    	{
    		if(root.val > val) 
    		{
    			root = root.left;
    		}else if(root.val < val) 
    		{
    			root = root.right;
    		}else 
    		{
    			return root;
    		}
    	}
    	return null;
    }

 LeetCode98.验证二叉搜索树

(1)递归

        基本思路:递归的三个步骤:

        1,确定递归函数的参数和返回值:要定义一个longlong的全局变量,用来比较遍历的节点是否有序,因为后台测试数据中有int最小值,所以定义为longlong的类型,初始化为longlong最小值。

        2,确定终止条件:如果是空节点 是不是二叉搜索树呢?是的,二叉搜索树也可以为空!

        3,确定单层的递归逻辑:中序遍历,一直更新maxVal,一旦发现maxVal >= root->val,就返回false,注意元素相同时候也要返回false。

Java代码如下:

    public boolean isValidBST(TreeNode root) {
    	return validBST(Long.MIN_VALUE, Long.MAX_VALUE, root);
    }
    
    boolean validBST(long lower, long upper, TreeNode root) {
        if (root == null) return true;
        if (root.val <= lower || root.val >= upper) return false;
        return validBST(lower, root.val, root.left) && validBST(root.val, upper, root.right);
    }

 

(2)迭代

        基本思路:可以用迭代法模拟二叉树中序遍历。

Java代码如下:

    //LeetCode 98 验证二叉搜索树 迭代
    public boolean isValidBST_1(TreeNode root) 
    {
    	if(root == null) 
    	{
    		return true;
    	}
    	Deque<TreeNode> stack = new ArrayDeque<>();
    	TreeNode pre = null;
    	while(root != null || !stack.isEmpty()) 
    	{
    		while(root != null) 
    		{
    			stack.push(root);
    			root = root.left;
    		}
    		TreeNode pop = stack.pop();
    		if(pre != null && pop.val <= pre.val) 
    		{
    			return false;
    		}
    		pre = pop;
    		root = pop.right;
    	}
    	
    	return true;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值