1.LeetCode 654.最大1二叉树
题目链接:力扣链接
视频讲解:
给定一个不重复的整数数组 nums
。 最大二叉树 可以用下面的算法从 nums
递归地构建:
- 创建一个根节点,其值为
nums
中的最大值。 - 递归地在最大值 左边 的 子数组前缀上 构建左子树。
- 递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums
构建的 最大二叉树 。
示例 1:
输入:nums = [3,2,1,6,0,5] 输出:[6,3,5,null,2,0,null,null,1] 解释:递归调用如下所示: - [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。 - [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。 - 空数组,无子节点。 - [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。 - 空数组,无子节点。 - 只有一个元素,所以子节点是一个值为 1 的节点。 - [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。 - 只有一个元素,所以子节点是一个值为 0 的节点。 - 空数组,无子节点。
思路:构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。
1.递归的返回值和传参:返回的是TreeNode,传参的话是数组类型的,我们新建一个方法来进行递归,那就要定好root节点2边的遍历位置,那就要传一个leftindex和一个rightindex的值,那就是传nums,int leftindex,int rightindexx;
2.确定递归的终止条件:当nums== 0的时候就返回null;当只有一个值的时候,也进行返回。
3.单边的递归条件:采用前序遍历,那优先处理中节点,找到一个最大值作为根节点,nums左边的是在左孩子,最大值的右边是有孩子,那么左孩子的递归条件就是,num,leftindex,maxindex(左闭右开),右节点的递归条件就是num,maxindex+1,rightindex;最后返回root节点
java代码具体如下:
class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
return rever(nums,0,nums.length);
}
public TreeNode rever(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 = rever(nums,leftIndex,maxIndex);
root.right = rever(nums,maxIndex+1,rightIndex);
return root;
}
}
2.LeetCode 617.合并二叉树
题目链接:力扣链接
视频讲解:B站视频讲解
给你两棵二叉树: root1
和 root2
。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。
示例 1:
输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7] 输出:[3,4,5,5,4,null,7]
递归思路:
1.确定传参和返回值:传参是2个treenode,root1和root2,返回值是treenode;
2.确定终止条件:root1为空就返回root2,root2为空就返回root1;
3.单边递归条件:同时传2个节点的值;
java代码如下:
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;
}
}
思路二:迭代法:
1.如果2个treenode有一个为空,则返回另外一个treenode;
2.创建栈,把root1和root2同时压入栈;
3.当栈不为空,开始层序遍历,走前序遍历,结合栈的特点(先进后出),我们优先压入右侧入栈,在压入左侧;
4.当2个左右都不为空,我们就将2个数据都入栈,如果其中一个为空,那我们就补充这个数字;
最后返回栈root;
java代码如下:
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if(root1 == null) return root2;
if(root2 == null) return root1;
Stack<TreeNode> stack = new Stack<>();
stack.push(root2);
stack.push(root1);
while (!stack.isEmpty()){
TreeNode temp1 = stack.pop();
TreeNode temp2 = stack.pop();
temp1.val += temp2.val;
if(temp1.right != null && temp2.right != null){
stack.push(temp2.right);
stack.push(temp1.right);
}else{
if(temp1.right ==null){
temp1.right = temp2.right;
}
}
if(temp1.left != null && temp2.left != null){
stack.push(temp2.left);
stack.push(temp1.left);
}else{
if(temp1.left ==null){
temp1.left = temp2.left;
}
}
}
return root1;
}
}
3.LeetCode 700.二叉搜索数中的搜索
题目链接:力扣链接
视频讲解:B站视频讲解
给定二叉搜索树(BST)的根节点 root
和一个整数值 val
。
你需要在 BST 中找到节点值等于 val
的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null
。
示例 1:
输入:root = [4,2,7,1,3], val = 2 输出:[2,1,3]
思路一:递归法:
二叉搜索树是一个有序树:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉搜索树
这就决定了,二叉搜索树,递归遍历和迭代遍历和普通二叉树都不一样
这道题,我们要进行后续遍历:是左,右,中,1要小于2,2要小于3,3要小于根节点4,如果不满足,那就return null;
遍历三大要素:
1.传参和返回值:返回treenode,传参是root和val值;
2.确定终止条件:当root为空或者root.val == val return root;
3.单边递归条件:采用前序遍历,中,左,右的一个遍历规则;找到了就立即返回,不在接着走后续。
java代码如下:
如果left不为空,那就说明左节点已经找到了和目标值一样的数据,此时,不用接着走了,我们返回left即可,如果没找到,那我们就遍历右节点,如果找到了,right就不为空,反之为空,我们返回即可。
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
if(root == null){
return root;
}
if(root.val == val){
return root;
}
TreeNode left = searchBST(root.left,val);
if(left != null){
return left;
}
TreeNode right = searchBST(root.right,val);
return right;
}
}
思路二:层序遍历(迭代法)
java代码如下:
我们还是走前序遍历:如果找到了temp.val ==val;我们就结束循环,反之,便利了整个二叉树,都没有找到,那就返回null;
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
if (root == null) {
return root;
}
if (root.val == val) {
return root;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
int size = stack.size();
while (size > 0) {
TreeNode temp = stack.pop();
if (temp.val == val) {
return temp;
}
if (temp.right != null) {
stack.push(temp.right);
}
if (temp.left != null) {
stack.push(temp.left);
}
size--;
}
}
return null;
}
}
4.LeetCode 98.验证搜索二叉树
题目链接:力扣链接
视频讲解:B站视频讲解
给你一个二叉树的根节点 root
,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:root = [2,1,3] 输出:true
思路:
二叉搜索树是一个有序树:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉搜索树
这就决定了,二叉搜索树,递归遍历和迭代遍历和普通二叉树都不一样
这道题,我们要进行中续遍历:是左,中,右
递归法:
1.确定传参和返回值:传参是root,返回值是boolean类型
2.终止条件:按照后续遍历,如果某个值比下一个遍历的值要大,那就return false;
3.单边递归条件:root.left和root.right,因为有返回值,所以需要接受返回值
class Solution {
// 定义一个前节点,默认为null
TreeNode max;
public boolean isValidBST(TreeNode root) {
if(root == null){
return true;
}
//左,如果左边已经不满足了,则直接返回false;
boolean left = isValidBST(root.left);
// 接下来的遍历,判断是不是比前面一个节点的数值要打,如果大就正确,如果小就返回false
if(max != null && max.val >= root.val){
return false;
}
// 第一次遍历,我们要将root的值赋值给max;
max =root;
// 右
boolean right = isValidBST(root.right);
return left && right;
}
}
思路二:迭代法
java代码如下:
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 pop = stack.pop();
if (pre != null && pop.val <= pre.val) {
return false;
}
pre = pop;
root = pop.right;// 右
}
return true;
}
}