[豪の算法奇妙冒险] 代码随想录算法训练营第十七天 | 654-最大二叉树、617-合并二叉树、700-二叉搜索树中的搜索、98-验证二叉搜索树
代码随想录算法训练营第十七天 | 654-最大二叉树、617-合并二叉树、700-二叉搜索树中的搜索、98-验证二叉搜索树
LeetCode654 最大二叉树
题目链接:https://leetcode.cn/problems/maximum-binary-tree/description/
文章讲解:https://programmercarl.com/0654.最大二叉树.html
视频讲解:https://www.bilibili.com/video/BV1MG411G7ox/?vd_source=b989f2b109eb3b17e8178154a7de7a51
构造二叉树一般采用前序遍历(中左右),先构造中间节点,然后递归构造左右子树
- 确定递归函数的参数和返回值
TreeNode buildMaximumBinaryTree(int[] nums, int left, int right)
为了避免重复构造数组,另外引入左右指针,采用左开右闭,最终返回的是该函数构造的二叉树的头节点
- 确定终止条件
当 right - left < 1 , 即 left >= right,说明区间已无元素,返回null
当 right - left == 1,说明区间只剩下一个元素,遍历到了叶子节点,返回构造的叶子节点即可
- 确定单层递归逻辑
先找到当前区间的maxValue和对应下标index,然后用maxValue构造节点curNode,接着将当前区间分为左区间 [left, index) 和右区间 [index + 1, right),分别进行递归构造curNode的左右子树

class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
return buildMaximumBinaryTree(nums, 0, nums.length);
}
public TreeNode buildMaximumBinaryTree(int[] nums, int left, int right){
if(right - left < 1){
return null;
}
if(right - left == 1){
return new TreeNode(nums[left]);
}
int maxValue = nums[left];
int index = left;
for(int i = left + 1; i < right; i++){
if(maxValue < nums[i]){
maxValue = nums[i];
index = i;
}
}
TreeNode curNode = new TreeNode(maxValue);
curNode.left = buildMaximumBinaryTree(nums, left, index);
curNode.right = buildMaximumBinaryTree(nums, index + 1, right);
return curNode;
}
}
LeetCode617 合并二叉树
题目链接:https://leetcode.cn/problems/merge-two-binary-trees/description/
文章讲解:https://programmercarl.com/0617.合并二叉树.html
视频讲解:https://www.bilibili.com/video/BV1m14y1Y7JK/?vd_source=b989f2b109eb3b17e8178154a7de7a51
这题涉及到同时操作两个二叉树,确保同步遍历两个二叉树即可

class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if(root1 == null){
return root2;
}
if(root2 == null){
return root1;
}
TreeNode curNode = new TreeNode(root1.val + root2.val);
curNode.left = mergeTrees(root1.left, root2.left);
curNode.right = mergeTrees(root1.right, root2.right);
return curNode;
}
}
LeetCode700 二叉搜索树中的搜索
题目链接:https://leetcode.cn/problems/search-in-a-binary-search-tree/description/
二叉搜索树是一个有序树:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉搜索树

class Solution {
public TreeNode searchBST(TreeNode root, int val) {
if(root == null || root.val == val){
return root;
}
TreeNode result = null;
if(val > root.val){
result = searchBST(root.right, val);
}
if(val < root.val){
result = searchBST(root.left, val);
}
return result;
}
}
LeetCode98 验证二叉搜索树
题目链接:https://leetcode.cn/problems/validate-binary-search-tree/
文章讲解:https://programmercarl.com/0098.验证二叉搜索树.html
视频讲解:https://www.bilibili.com/video/BV18P411n7Q4/?vd_source=b989f2b109eb3b17e8178154a7de7a51
关键在于要了解二叉搜索树的特性,若二叉搜索树合法,则使用中序遍历(左中右)产生的结果数组是递增的

class Solution {
public boolean isValidBST(TreeNode root) {
List<Integer> result = new ArrayList<>();
midOrder(root, result);
if(result.size() == 1){
return true;
}else{
for(int i = 1; i < result.size(); i++){
if(result.get(i) <= result.get(i-1)){
return false;
}
}
}
return true;
}
public void midOrder(TreeNode node, List<Integer> result){
if(node == null){
return;
}
if(node.left != null){
midOrder(node.left, result);
}
result.add(node.val);
if(node.right != null){
midOrder(node.right, result);
}
}
}
采用双指针思路进行优化,只需遍历时与前一个节点进行比较,就不用额外建立数组判断是否递增

class Solution {
TreeNode preNode;
public boolean isValidBST(TreeNode root) {
if(root == null){
return true;
}
boolean left = isValidBST(root.left);
if(!left){
return false;
}
if(preNode != null && root.val <= preNode.val){
return false;
}
preNode = root;
boolean right = isValidBST(root.right);
return right;
}
}

浙公网安备 33010602011771号