题目:
654. 最大二叉树
给定一个不重复的整数数组
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 的节点。 - 空数组,无子节点。示例 2:
输入:nums = [3,2,1] 输出:[3,null,2,null,1]提示:
1 <= nums.length <= 1000
0 <= nums[i] <= 1000
nums
中的所有整数 互不相同
思路:
1.凡是构造二叉树类的题目,都要用前序遍历(中左右)
2.终止条件,当数组大小等于1时,说明要构造的是叶子节点,返回node
算法:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func constructMaximumBinaryTree(nums []int) *TreeNode {
if len(nums) == 1 {
return &TreeNode{Val:nums[0]}
}
maxv, index := nums[0], 0
//寻找数组最大值,最大值为根节点
for i := 1; i < len(nums); i++ {
if nums[i] > maxv{
maxv = nums[i]
index = i
}
}
node := &TreeNode{Val:maxv}
//构造左子树
if index > 0 {
node.Left = constructMaximumBinaryTree(nums[:index])
}
//构造右子树 注意index范围
if index < len(nums)-1 {
node.Right = constructMaximumBinaryTree(nums[index+1:])
}
return node
}
注意:
1.注意循环递归时index左右区间的判断
2.本题解题采用左闭右开区间
题目:
617. 合并二叉树
给你两棵二叉树:
root1
和root2
。想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。
示例 1:
输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7] 输出:[3,4,5,5,4,null,7]示例 2:
输入:root1 = [1], root2 = [1,2] 输出:[2,2]提示:
- 两棵树中的节点数目在范围
[0, 2000]
内-104 <= Node.val <= 104
思路:
1.本题考查同时操作两个二叉树
2.采用前序遍历比较直观
算法:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
//循环终止条件
if root1 == nil {
return root2
}
if root2 == nil {
return root1
}
//前序遍历,处理中节点
new_root := &TreeNode{}
new_root.Val = root1.Val+root2.Val
//处理左子树
new_root.Left = mergeTrees(root1.Left, root2.Left)
//处理右子树
new_root.Right = mergeTrees(root1.Right,root2.Right)
return new_root
}
注意:
题目:
700. 二叉搜索树中的搜索
给定二叉搜索树(BST)的根节点
root
和一个整数值val
。你需要在 BST 中找到节点值等于
val
的节点。 返回以该节点为根的子树。 如果节点不存在,则返回null
。示例 1:
输入:root = [4,2,7,1,3], val = 2 输出:[2,1,3]示例 2:
输入:root = [4,2,7,1,3], val = 5 输出:[]提示:
- 树中节点数在
[1, 5000]
范围内1 <= Node.val <= 107
root
是二叉搜索树1 <= val <= 107
思路:
1.二叉搜索树定义:根节点比左子树的所有节点都大,根节点比右子树的所有节点都小
2.递归法可以利用二叉搜索树的特性解题
3.本题迭代法也很简单
算法:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func searchBST(root *TreeNode, val int) *TreeNode {
if root == nil {
return nil
}
//中节点
if root.Val == val {
return root
}
//利用二叉搜索树的特性
var new_node *TreeNode
if val > root.Val {
new_node = searchBST(root.Right, val)
}
if val < root.Val {
new_node = searchBST(root.Left, val)
}
return new_node
}
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
//迭代法
func searchBST(root *TreeNode, val int) *TreeNode {
if root == nil {
return nil
}
//中节点
if root.Val == val {
return root
}
for root != nil {
if root.Val == val {
return root
} else if root.Val > val {
root = root.Left
} else {
root = root.Right
}
}
return nil
}
注意:二叉搜索树特性
题目:
已解答
中等
相关标签
相关企业
给你一个二叉树的根节点
root
,判断其是否是一个有效的二叉搜索树。有效 二叉搜索树定义如下:
- 节点的左
子树
只包含 小于 当前节点的数。- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:root = [2,1,3] 输出:true示例 2:
输入:root = [5,1,4,null,null,3,6] 输出:false 解释:根节点的值是 5 ,但是右子节点的值是 4 。提示:
- 树中节点数目范围在
[1, 104]
内-231 <= Node.val <= 231 - 1
思路:
1.把二叉树转变为数组来判断,是最直观的
2.中序递归直接比较,当前节点要大于它的前一个节点
算法:
//方法一:申请数组,中序入数组,判断是否单调递增
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isValidBST(root *TreeNode) bool {
//如果树为空,那么树是二叉搜索树
if root == nil {
return true
}
//直接解法,申请数组,按中序遍历append进数组
tmp := make([]int,0)
var push func(node *TreeNode)
push = func(node *TreeNode) {
if node != nil {
push(node.Left)
tmp = append(tmp, node.Val)
push(node.Right)
}
}
push(root)
//判断数组是不是递增
for j := 1; j < len(tmp); j++{
if tmp[j] <= tmp[j-1]{
return false
}
}
return true
}
//方法二:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isValidBST(root *TreeNode) bool {
var pre_n *TreeNode //保存上一个指针
var travel func(node *TreeNode) bool
travel = func(node *TreeNode) bool {
//如果节点为空,那么是二叉搜索树
if node == nil {
return true
}
lr := travel(node.Left)
if pre_n != nil && node.Val <= pre_n.Val {
return false
}
pre_n = node
rr := travel(node.Right)
return lr && rr
}
return travel(root)
}
注意:
陷阱:不能通过root.val >root.Left.val && root.val < root.right.val来判断是否是二叉搜索树,root.val需要大于左子树所有的节点,而不仅只大于左节点