码随想录-算法训练营day20【二叉树06:最大二叉树、合并二叉树、二叉搜索树中的搜索、验证二叉搜索树】

本文主要是介绍码随想录-算法训练营day20【二叉树06:最大二叉树、合并二叉树、二叉搜索树中的搜索、验证二叉搜索树】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客

第六章 二叉树 part06
今日内容 ● 654.最大二叉树 
● 617.合并二叉树 
● 700.二叉搜索树中的搜索 
● 98.验证二叉搜索树 详细布置 654.最大二叉树 又是构造二叉树,昨天大家刚刚做完 中序后序确定二叉树,今天做这个 应该会容易一些, 先看视频,好好体会一下 为什么构造二叉树都是 前序遍历 题目链接/文章讲解:https://programmercarl.com/0654.%E6%9C%80%E5%A4%A7%E4%BA%8C%E5%8F%89%E6%A0%91.html  
视频讲解:https://www.bilibili.com/video/BV1MG411G7ox  617.合并二叉树 这次是一起操作两个二叉树了, 估计大家也没一起操作过两个二叉树,也不知道该如何一起操作,可以看视频先理解一下。 优先掌握递归。题目链接/文章讲解:https://programmercarl.com/0617.%E5%90%88%E5%B9%B6%E4%BA%8C%E5%8F%89%E6%A0%91.html  
视频讲解:https://www.bilibili.com/video/BV1m14y1Y7JK  700.二叉搜索树中的搜索 递归和迭代 都可以掌握以下,因为本题比较简单, 了解一下 二叉搜索树的特性题目链接/文章讲解: https://programmercarl.com/0700.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E6%90%9C%E7%B4%A2.html  
视频讲解:https://www.bilibili.com/video/BV1wG411g7sF   98.验证二叉搜索树 遇到 搜索树,一定想着中序遍历,这样才能利用上特性。 但本题是有陷阱的,可以自己先做一做,然后在看题解,看看自己是不是掉陷阱里了。这样理解的更深刻。题目链接/文章讲解:https://programmercarl.com/0098.%E9%AA%8C%E8%AF%81%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html 
视频讲解:https://www.bilibili.com/video/BV18P411n7Q4  
往日任务
● day 1 任务以及具体安排:https://docs.qq.com/doc/DUG9UR2ZUc3BjRUdY  
● day 2 任务以及具体安排:https://docs.qq.com/doc/DUGRwWXNOVEpyaVpG  
● day 3 任务以及具体安排:https://docs.qq.com/doc/DUGdqYWNYeGhlaVR6 
● day 4 任务以及具体安排:https://docs.qq.com/doc/DUFNjYUxYRHRVWklp 
● day 5 周日休息
● day 6 任务以及具体安排:https://docs.qq.com/doc/DUEtFSGdreWRuR2p4 
● day 7 任务以及具体安排:https://docs.qq.com/doc/DUElCb1NyTVpXa0Jj 
● day 8 任务以及具体安排:https://docs.qq.com/doc/DUGdsY2JFaFhDRVZH 
● day 9 任务以及具体安排:https://docs.qq.com/doc/DUHVXSnZNaXpVUHN4 
● day 10 任务以及具体安排:https://docs.qq.com/doc/DUElqeHh3cndDbW1Q 
●day 11 任务以及具体安排:https://docs.qq.com/doc/DUHh6UE5hUUZOZUd0 
●day 12 周日休息 
●day 13 任务以及具体安排:https://docs.qq.com/doc/DUHNpa3F4b2dMUWJ3 
●day 14 任务以及具体安排:https://docs.qq.com/doc/DUHRtdXZZSWFkeGdE 
●day 15 任务以及具体安排:https://docs.qq.com/doc/DUHN0ZVJuRmVYeWNv 
●day 16 任务以及具体安排:https://docs.qq.com/doc/DUHBQRm1aSWR4T2NK 
●day 17 任务以及具体安排:https://docs.qq.com/doc/DUFpXY3hBZkpabWFY 
●day 18 任务以及具体安排:https://docs.qq.com/doc/DUFFiVHl3YVlReVlr 
●day 19 周日休息

目录

0654_最大二叉树

0617_合并二叉树

0700_二叉搜索树中的搜索

0098_验证二叉搜索树


0654_最大二叉树

根据数组构造二叉树

  1. ​​​​106.从中序与后序遍历序列构造二叉树
  2. 105.从前序与中序遍历序列构造二叉树
  3. 654.最大二叉树
package com.question.solve.leetcode.programmerCarl2._07_binaryTrees;public class _0654_最大二叉树 {
}/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution0654 {public TreeNode constructMaximumBinaryTree(int[] nums) {return compute(nums, 0, nums.length);}private TreeNode compute(int[] nums, int leftIndex, int rightIndex) {if (rightIndex - leftIndex < 1) {//没有元素了return null;}if (rightIndex - leftIndex == 1) {return new TreeNode(nums[leftIndex]);}int maxValue = nums[leftIndex], maxIndex = leftIndex;for (int i = leftIndex + 1; i < rightIndex; i++) {if (maxValue < nums[i]) {maxValue = nums[i];maxIndex = i;}}TreeNode leftNode = compute(nums, leftIndex, maxIndex);TreeNode rightNode = compute(nums, maxIndex + 1, rightIndex);return new TreeNode(maxValue, leftNode, rightNode);}
}class Solution0654_2 {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;}
}class Solution0654_3 {public TreeNode constructMaximumBinaryTree(int[] nums) {return construct(nums, 0, nums.length - 1);}public TreeNode construct(int[] nums, int left, int right) {if (left > right) {return null;}int best = left;for (int i = left + 1; i <= right; ++i) {if (nums[i] > nums[best]) {best = i;}}TreeNode node = new TreeNode(nums[best]);node.left = construct(nums, left, best - 1);node.right = construct(nums, best + 1, right);return node;}
}

0617_合并二叉树

package com.question.solve.leetcode.programmerCarl2._07_binaryTrees;import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;public class _0617_合并二叉树 {
}/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution0617 {public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {if (root1 == null) {return root2;}if (root2 == null) {return root1;}Queue<TreeNode> queue = new LinkedList<>();queue.offer(root1);queue.offer(root2);while (!queue.isEmpty()) {TreeNode node1 = queue.poll();TreeNode node2 = queue.poll();//此时两个节点一定不为空,val相加node1.val = node1.val + node2.val;//如果两棵树左节点都不为空,加入队列if (node1.left != null && node2.left != null) {queue.offer(node1.left);queue.offer(node2.left);}//如果两棵树右节点都不为空,加入队列if (node1.right != null && node2.right != null) {queue.offer(node1.right);queue.offer(node2.right);}//若node1的左节点为空,直接赋值if (node1.left == null && node2.left != null) {node1.left = node2.left;}//若node1的右节点为空,直接赋值if (node1.right == null && node2.right != null) {node1.right = node2.right;}}return root1;}public TreeNode mergeTrees2(TreeNode t1, TreeNode t2) {if (t1 == null) {return t2;}if (t2 == null) {return t1;}TreeNode merged = new TreeNode(t1.val + t2.val);merged.left = mergeTrees2(t1.left, t2.left);merged.right = mergeTrees2(t1.right, t2.right);return merged;}
}class Solution0617_2 {//递归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;}//使用栈迭代public TreeNode mergeTrees2(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 node1 = stack.pop();TreeNode node2 = stack.pop();node1.val += node2.val;if (node2.right != null && node1.right != null) {stack.push(node2.right);stack.push(node1.right);} else {if (node1.right == null) {node1.right = node2.right;}}if (node2.left != null && node1.left != null) {stack.push(node2.left);stack.push(node1.left);} else {if (node1.left == null) {node1.left = node2.left;}}}return root1;}//使用队列迭代public TreeNode mergeTrees3(TreeNode root1, TreeNode root2) {if (root1 == null) return root2;if (root2 == null) return root1;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root1);queue.offer(root2);while (!queue.isEmpty()) {TreeNode node1 = queue.poll();TreeNode node2 = queue.poll();//此时两个节点一定不为空,val相加node1.val = node1.val + node2.val;//如果两棵树左节点都不为空,加入队列if (node1.left != null && node2.left != null) {queue.offer(node1.left);queue.offer(node2.left);}//如果两棵树右节点都不为空,加入队列if (node1.right != null && node2.right != null) {queue.offer(node1.right);queue.offer(node2.right);}//若node1的左节点为空,直接赋值if (node1.left == null && node2.left != null) {node1.left = node2.left;}//若node1的右节点为空,直接赋值if (node1.right == null && node2.right != null) {node1.right = node2.right;}}return root1;}
}

0700_二叉搜索树中的搜索

解决二叉树题目,优先使用递归。
递归法
1.确定递归函数的参数和返回值;
2.确定终止条件;
3.确定单层递归的逻辑。

package com.question.solve.leetcode.programmerCarl2._07_binaryTrees;import java.util.Deque;
import java.util.LinkedList;
import java.util.Stack;public class _0700_二叉搜索树中的搜索 {
}class Solution0700 {//递归,普通二叉树public TreeNode searchBST(TreeNode root, int val) {if (root == null || root.val == val) {return root;}TreeNode left = searchBST(root.left, val);if (left != null) {return left;}return searchBST(root.right, val);}
}class Solution0700_2 {//递归,利用二叉搜索树特点,优化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 Solution0700_3 {//迭代,普通二叉树public TreeNode searchBST(TreeNode root, int val) {if (root == null || root.val == val) {return root;}Stack<TreeNode> stack = new Stack<>();stack.push(root);while (!stack.isEmpty()) {TreeNode pop = stack.pop();if (pop.val == val) {return pop;}if (pop.right != null) {stack.push(pop.right);}if (pop.left != null) {stack.push(pop.left);}}return null;}public TreeNode searchBST2(TreeNode root, int val) {Deque<TreeNode> deque = new LinkedList<>();deque.offer(root);while (!deque.isEmpty()) {TreeNode poll = deque.poll();if (poll != null && poll.val == val) {return poll;}if (poll.val < val && poll.right != null) {deque.offer(poll.right);} else if (poll.val > val && poll.left != null) {deque.offer(poll.left);}}return null;}
}class Solution0700_4 {//迭代,利用二叉搜索树特点,优化,可以不需要栈public TreeNode searchBST(TreeNode root, int val) {while (root != null)if (val < root.val) root = root.left;else if (val > root.val) root = root.right;else return root;return null;}
}

0098_验证二叉搜索树

package com.question.solve.leetcode.programmerCarl2._07_binaryTrees;import java.util.ArrayList;
import java.util.List;
import java.util.Stack;public class _0098_验证二叉搜索树 {
}/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution0098 {List<Integer> list = new ArrayList<Integer>();public boolean isValidBST(TreeNode root) {if (root == null) {return true;}inOrder(root);//将 ArrayList 转换为 int 数组int[] intArray = list.stream().mapToInt(Integer::intValue).toArray();for (int i = 0; i < intArray.length - 1; i++) {if (intArray[i] >= intArray[i + 1]) {return false;}}return true;//Object[] array1 = list.toArray();
//        List<Integer> list2 = list;
//        Collections.sort(list2);
//        if (list.toString().equals(list2.toString())) {
//            return true;
//        } else {
//            return false;
//        }}private void inOrder(TreeNode root) {if (root == null) {return;}inOrder(root.left);list.add(root.val);inOrder(root.right);}
}//使用统一迭代法
class Solution0098_2 {//使用统一迭代法public boolean isValidBST(TreeNode root) {Stack<TreeNode> stack = new Stack<>();TreeNode pre = null;if (root != null)stack.add(root);while (!stack.isEmpty()) {TreeNode curr = stack.peek();if (curr != null) {stack.pop();if (curr.right != null)stack.add(curr.right);stack.add(curr);stack.add(null);if (curr.left != null)stack.add(curr.left);} else {stack.pop();TreeNode temp = stack.pop();if (pre != null && pre.val >= temp.val)return false;pre = temp;}}return true;}
}class Solution0098_3 {// 递归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 Solution0098_4 {// 迭代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;}
}// 简洁实现·递归解法
class Solution0098_5 {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);}
}// 简洁实现·中序遍历
class Solution0098_6 {private long prev = Long.MIN_VALUE;public boolean isValidBST(TreeNode root) {if (root == null) {return true;}if (!isValidBST(root.left)) {return false;}if (root.val <= prev) { //不满足二叉搜索树条件return false;}prev = root.val;return isValidBST(root.right);}
}class Solution0098_7 {public boolean isValidBST(TreeNode root) {return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);}public boolean isValidBST(TreeNode node, long lower, long upper) {if (node == null) {return true;}if (node.val <= lower || node.val >= upper) {return false;}return isValidBST(node.left, lower, node.val) && isValidBST(node.right, node.val, upper);}
}

这篇关于码随想录-算法训练营day20【二叉树06:最大二叉树、合并二叉树、二叉搜索树中的搜索、验证二叉搜索树】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/927735

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名