leetcode每周3道(五)二叉树

110.平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

leetcode每周3道(五)二叉树_第1张图片

 1、自己的第一想法:

思路:算出每一个结点的最大深度,再对每一个结点的左右孩子算最大深度差。倒着算应该会快些。但是这里没有有效的利用底层结点求出来的深度。

时O(n^2) 空O(n)

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isBalanced(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        if not root:
            return True
#求1个结点的最大深度
        def balance(root):
            if not root:
                return 0
            return 1+max(balance(root.left),balance(root.right))
#遍历所有非空结点
        stack = []
        def store(root):
            if root:
                stack.append(root)
                store(root.left)
                store(root.right)
        store(root)  
#对所有结点判断左右孩子的最大深度差,从叶子节点开始反着判断,应该会快一点。  
        while stack:
            root = stack.pop()
            if abs(balance(root.left)-balance(root.right))>1:
                return False
        return True
        

leetcode每周3道(五)二叉树_第2张图片

 2、自顶向下(暴力法)

思路:先递归的算出每一个结点的最大深度,再递归的判断当前节点的左右子树是否维平衡二叉树。时O(n^2) 空O(n)

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
#求节点最大深度
    def balance(self,root):
        if not root:
            return 0
        return 1+max(self.balance(root.left),self.balance(root.right))

    def isBalanced(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        if not root:
            return True
#递归的判断左右子树是否平衡
        return abs(self.balance(root.left)-self.balance(root.right))<=1 and self.isBalanced(root.left) and self.isBalanced(root.right)

leetcode每周3道(五)二叉树_第3张图片

3、自底向上(时间优化)想不到不会写

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isBalanced(self, root):
        return self.depth(root) != -1

    def depth(self, root):
        if not root: return 0
        left = self.depth(root.left)
        if left == -1: return -1
        right = self.depth(root.right)
        if right == -1: return -1
        return max(left, right) + 1 if abs(left - right) < 2 else -1

235.二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”leetcode每周3道(五)二叉树_第4张图片

运用二叉搜索树的性质,二者一个比根节点的值大,一个比之小,则公共祖先就是根节点;如果都比根节点小,公共祖先在左子树;否则在右子树。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        if not root:
            return
        elif p.valroot.val and q.val>root.val:
            return self.lowestCommonAncestor(root.right,p,q)
        else:
            return root

 leetcode每周3道(五)二叉树_第5张图片

 257.二叉树的所有路径

回溯法模板:如果当前节点为叶子节点就加入ans数组中,否则就回溯左右节点。由于path初始化为‘’,这里不用回溯pop了,如果是用path是一个list,后面就要pop了,因为list经过前面的操作会改变。而用''初始化path,对于同一回溯树层上的path是一样的,所以不用pop回溯了。(猜测)

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def binaryTreePaths(self, root):
        """
        :type root: TreeNode
        :rtype: List[str]
        """
        def backtrack(path,root):
            if root:
                path += str(root.val)
                if not root.left and not root.right:
                    ans.append(path)
                else:
                    path += '->'
                    backtrack(path,root.left)
                    #path.pop()
                    backtrack(path,root.right)
                    #path.pop()
        ans = []
        backtrack('',root)
        return ans

leetcode每周3道(五)二叉树_第6张图片

 

你可能感兴趣的:(Leetcode,leetcode,学习,算法)