22年40周

目录

一、翻转二叉树

二、对称二叉树

三、二叉树的最大深度

四、二叉树的最小深度

五、完全二叉树的节点个数

六:平衡二叉树

七、二叉树的所有路径

八、左叶子之和

九、找树左下角的值


一、翻转二叉树

题目:翻转二叉树

思路:直接用前序或者后续遍历,挨个儿反转就行了。

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func invertTree(root *TreeNode) *TreeNode {
    if root == nil {
        return nil
    }
    temp := root.Left
    root.Left = root.Right
    root.Right = temp

    invertTree(root.Left)
    invertTree(root.Right)
    return root
}

二、对称二叉树

题目:对称二叉树

思路:利用递归,去遍历根节点左右孩子的节点,之后进行比较。但是他说的镜像对称,不是对比是否一样,所以左右两棵子树遍历的先后顺序是不同的。

层次遍历这道题也是ok的,就是左子树从左向右,右子树从右往左。

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func isSymmetric(root *TreeNode) bool {

    return preOrderTwo(root.Left,root.Right)
}

func preOrderTwo (l *TreeNode,r *TreeNode) bool {

    if l == nil && r == nil {
        return true
    }

    if l == nil || r == nil {
        return false
    }

    if l.Val != r.Val {
        return false
    }

    lBool := preOrderTwo(l.Right,r.Left)
    rBool := preOrderTwo(l.Left,r.Right)

    return lBool && rBool
}

层次遍历方法

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:
        if not root or (root.left == None and root.right == None):
            return True
        leftStack = list()
        rightStack = list()
        leftStack.append(root.left)
        rightStack.append(root.right)

        while leftStack and rightStack:
            l = leftStack.pop()
            r = rightStack.pop()

            if l != None and r != None:
                if l.val != r.val:
                    return False
                leftStack.append(l.right)
                leftStack.append(l.left)
                rightStack.append(r.left)
                rightStack.append(r.right)
            elif l == None and r == None:
                continue
            else:
                return False
        return True





三、二叉树的最大深度

题目:二叉树的最大深度

思路;利用递归遍历,分别记录下左右子树的最大深度,当前节点的最大深度是左右子树中深度比较大的中的一个再加一就是当前节点的最大深度。

func maxDepth(root *TreeNode) int {
    if root == nil {
        return 0
    }

    l := maxDepth(root.Left)
    r := maxDepth(root.Right)

    max := l 
    if max < r {
        max = r
    }

    return max+1
}

四、二叉树的最小深度

题目:二叉树的最小深度

思路:其实和最大深度是一个思路,只不过有个问题需要考虑下,就是加入这颗树只有右子树,他的最小深度可能是节点个数,而不是0.

func minDepth(root *TreeNode) int {
    if root == nil {
        return 0
    }

    l := minDepth(root.Left)
    r := minDepth(root.Right)

    //防止出现只有一个孩子的时候的误判
    if l == 0 {
        return r + 1
    }

    if r == 0 {
        return l + 1
    }

    min := l 
    if min > r {
        min = r
    }

    return min+1
}

五、完全二叉树的节点个数

题目: 完全二叉树的节点个数

思路:两个思路,第一个是直接求树种节点的个数。

第二个思路用到了满二叉树的性质。

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
//正常写法
func countNodes(root *TreeNode) int {
    if root == nil {
        return 0
    }

    l := countNodes(root.Left)
    r := countNodes(root.Right)

    return l + r + 1 
}


/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
//利用满二叉树的性质
func countNodes(root *TreeNode) int {
    if root == nil {
        return 0
    }

    lHigh,rHigh := 0,0
    lptr,rptr := root,root 
    for lptr.Left != nil {
        lptr = lptr.Left
        lHigh++
    }

    for rptr.Right != nil {
        rptr = rptr.Right
        rHigh++
    }

    if rHigh == lHigh {
        return (2 << lHigh) - 1
    }

    l := countNodes(root.Left)
    r := countNodes(root.Right)

    return l + r + 1 
}

六:平衡二叉树

题目:平衡二叉树

思路,利用求二叉树深度的方式计算左右孩子深度是多少,计算完深度之后计算两者的差值,一旦差值大于1,就不用再进行遍历了。

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func isBalanced(root *TreeNode) bool {
    if root == nil {
        return true
    }

    depth := depth(root)
    
    if depth == -1 {
        return false
    }

    return true
}

//其实可以理解成,在求树的的深度的同时,计算改子树是不是平衡二叉树
func depth(root *TreeNode) int {
    if root == nil {
        return 0
    }

    l := depth(root.Left)
    if l == -1 {
        return -1
    }
    r := depth(root.Right)
    if r == -1 {
        return -1
    }

    if math.Abs(float64(l - r)) > 1 {
        return -1
    }

    max := l 
    if max < r {
        max = r
    }
    return max + 1
}

七、二叉树的所有路径

二叉树的所有路径

思路:就是利用先序遍历完成的,其中回涉及到遍历回溯的问题

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func binaryTreePaths(root *TreeNode) []string {
    res := make([]string,0)
    preOrder(root,&res,"")
    return res
}



func preOrder(root *TreeNode,res *[]string,route string) {

    if root == nil {//说明访问到根节点了
        return
    }
    
    if root.Left == nil && root.Right == nil {
        route = route + strconv.Itoa(root.Val)
        *res = append(*res,route)
        return
    }

    route = route + strconv.Itoa(root.Val)  + "->"

    preOrder(root.Left,res,route)
    preOrder(root.Right,res,route)

}

八、左叶子之和

左叶子之和

思路:遍历过程中传一个参数就是flag,用来判断是否从左子树过来的。

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func sumOfLeftLeaves(root *TreeNode) int {
    res := 0
    preOrder(root,&res,false)
    return res
}

func preOrder(root *TreeNode,res *int,flag bool) {

    if root.Left == nil && root.Right == nil && flag {
        *res = *res + root.Val
        return
    }

    if root.Left != nil {
        preOrder(root.Left,res,true)
    }

    if root.Right != nil {
         preOrder(root.Right,res,false)
    }
}

九、找树左下角的值

题目:找树左下角的值

思路:利用层次遍历或者递归遍历都行,目的就是为了找到层次数最大的,并且第一个出现在遍历顺序中的节点。

递归法:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
 var maxDeep = -1
func findBottomLeftValue(root *TreeNode) int {
    if root.Left==nil&&root.Right==nil{//需要提前判断一下(不要这个if的话提交结果会出错,但执行代码不会。防止这种情况出现,故先判断是否只有一个节点)
         return root.Val
     }
    res := 0
    deepth(root,&res,0)
    return res
}

func deepth(root *TreeNode,res *int,deep int) {

    if root.Left == nil && root.Right == nil && deep > maxDeep {
        *res = root.Val
        maxDeep = deep
       return
    }

    if root.Left != nil {
        deep++
        deepth(root.Left,res,deep)
        deep--
    }

    if root.Right != nil {
        deep++
        deepth(root.Right,res,deep)
        deep--
    }
}

层次法:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func findBottomLeftValue(root *TreeNode) int {

    l := list.New()//层次遍历队列
    curlen := 1
    nextlen := 0
    l.PushBack(root)
    res := root.Val

    for l.Len() > 0 {

        ptr := l.Remove(l.Front()).(*TreeNode)
        curlen--

        if ptr.Left != nil {
            l.PushBack(ptr.Left)
            nextlen++
        }

        if ptr.Right != nil {
            l.PushBack(ptr.Right)
            nextlen++
        }

        if curlen == 0{
            if l.Len() > 0 {
                p := l.Front().Value.(*TreeNode)
                res = p.Val
            }
            
            curlen = nextlen
            nextlen = 0
        }

    }

    return res


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值