目录
1.路径总和
题目地址:路径总和
思路:这道题应该用先序的递归遍历来解决,当遍历到叶子节点就判断,总和是否为targetsum。是的话则返回true,否则false
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func hasPathSum(root *TreeNode, targetSum int) bool {
if root == nil {
return false
}
targetSum -= root.Val // 将targetSum在遍历每层的时候都减去本层节点的值
if root.Left == nil && root.Right == nil && targetSum == 0 { // 如果剩余的targetSum为0, 则正好就是符合的结果
return true
}
return hasPathSum(root.Left, targetSum) || hasPathSum(root.Right, targetSum) // 否则递归找
}
2.从中序与后序遍历序列构造二叉树
链接地址:从中序与后序遍历序列构造二叉树
思想,构造树的过程也是一个递归的过程,从中序和后序中构造二叉树、中序和先序构造二叉树。这两道题的思想时一致的。先从后序遍历中找到根节点的值,之后在中序遍历中找到根节点的值,中序遍历中根节点的边的值是左子树序列,右边是右子树序列。后序遍历中同样是如此,找到根节点的左右子树序列。之后传入到下一轮的递归中。
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func buildTree(inorder []int, postorder []int) *TreeNode {
if len(postorder) == 0{
return nil
}
rootVal := postorder[len(postorder)-1]
root := &TreeNode{rootVal,nil,nil}
inorderIndex := 0
for k,v := range inorder {
if v == rootVal {
inorderIndex = k
break
}
}
root.Left = buildTree(inorder[:inorderIndex],postorder[:inorderIndex])
root.Right = buildTree(inorder[inorderIndex+1:],postorder[inorderIndex:len(postorder)-1])
return root
}
3.最大二叉树
思路:这道题和2中的思路很像,只不过是改成寻找最大值了
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func constructMaximumBinaryTree(nums []int) *TreeNode {
if len(nums) == 0 {
return nil
}
max := nums[0]
maxIndex := 0
for k,v := range nums {
if max < v {
max = v
maxIndex = k
}
}
root := &TreeNode{max,nil,nil}
root.Left = constructMaximumBinaryTree(nums[:maxIndex])
//这块不用写if判断是否出界的原因是因为[4:4]也是合法的,但是[5:4]就不合法了
root.Right = constructMaximumBinaryTree(nums[maxIndex+1:])
return root
}
4.合并二叉树
链接:合并二叉树
思想:先序遍历树,可以创建一个新的节点,也可以在两棵子树中的某一棵树上进行操作。
func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
if root1 == nil {
return root2
}
if root2 == nil {
return root1
}
root1.Val += root2.Val
root1.Left = mergeTrees(root1.Left, root2.Left)
root1.Right = mergeTrees(root1.Right, root2.Right)
return root1
}
5.二叉搜索树中的搜索
链接:二叉搜索树中的搜索
思想:直接利用递归遍历查找即可,找到就返回。
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func searchBST(root *TreeNode, val int) *TreeNode {
if root.Val == val {
return root
}
if root.Left != nil && root.Val > val{
return searchBST(root.Left,val)
}
if root.Right != nil && root.Val < val{
return searchBST(root.Right,val)
}
return nil
}
6.验证二叉搜索树
思路:分为两种,一种递归法,一种是迭代法,总体思路都是,BST的中序遍历是有序的。递归法需要在递归过程中记录pre节点来完成比较工作。
//二叉搜索树的中序遍历是个有序序列
func isValidBST(root *TreeNode) bool {
res := make([]int,0)
if root == nil {
return false
}
stack := make([]*TreeNode,0)
cur := root
//迭代法
for cur != nil || len(stack) > 0 {
if cur != nil {
stack = append(stack,cur)
cur = cur.Left
}else {
cur = stack[len(stack) - 1]
res = append(res,cur.Val)
stack = stack[:len(stack)-1]
cur = cur.Right
}
}
for i:=0;i<len(res)-1;i++ {
if res[i] >= res[i+1] {
return false
}
}
return true
}
//递归方法
func isValidBST(root *TreeNode) bool {
// 保存上一个指针
var prev *TreeNode
var travel func(node *TreeNode) bool
travel = func(node *TreeNode) bool {
if node == nil {
return true
}
leftRes := travel(node.Left)
// 当前值小于等于前一个节点的值,返回false
if prev != nil && node.Val <= prev.Val {
return false
}
prev = node
rightRes := travel(node.Right)
return leftRes && rightRes
}
return travel(root)
}