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;
}