leetcode 树(二)判断二叉树

leetcode 98,96,95,101,offer28,offer27,110,offer55,offer26

  • 二叉搜索树
    • leetcode98 验证二叉搜索树
    • leetcode 不同的BST组合数
      • leetcode96
      • leetcode95
  • 对称二叉树
    • leetcode101 & offer28 判断是否是对称的二叉树
    • offer面试题27 输出二叉树的镜像
  • 平衡二叉树
    • leetcode110 & offer55 判断是否是平衡的二叉树
  • 树的子结构
    • offer26 判断树B是否是树A的子结构

二叉搜索树

二叉搜索树具有如下特征:

  1. 节点的左子树只包含小于当前节点的数。
  2. 节点的右子树只包含大于当前节点的数。
  3. 所有左子树和右子树自身必须也是二叉搜索树。

leetcode98 验证二叉搜索树

题目:给定一个二叉树,判断其是否是一个有效的二叉搜索树。

中序遍历,若单增,则是有效的二叉搜索树。
不用全部遍历之后再判断,可以设置初始比较值为负无穷:prevalue = float(’-inf’),然后更新比较值为中序遍历到的节点值:prevalue = move.val,新的中序遍历节点值大于比较值就行。

class Solution(object):
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        if not root:
            return True
        stack = []
        move = root
        prevalue = float('-inf')
        while stack or move:
            while move:
                stack.append(move)
                move = move.left
            move = stack.pop()
            if move.val <= prevalue:
                return False
            prevalue = move.val
            move = move.right
        return True

leetcode 不同的BST组合数

leetcode96

题目:给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?

输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-binary-search-trees
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

数学题,我想不出来。去看:官方答案。

class Solution(object):
    def numTrees(self, n):
        """
        :type n: int
        :rtype: int
        """
        # G(n) = sigma 1-n [G(i-1)*G(n-i)]
        
        G = [0] * (n+1)
        G[0], G[1] = 1, 1
        for i in range(2,n+1):
            for j in range(1,i+1):
                G[i] += G[j-1] * G[i-j]
        return G[n]

leetcode95

题目:给定一个整数 n,生成所有由 1 … n 为节点所组成的 二叉搜索树 。

输入:3
输出:
[
  [1,null,3,2],
  [3,2,null,1],
  [3,1,null,null,2],
  [2,1,3],
  [1,null,2,null,3]
]
解释:
以上的输出对应以下 5 种不同结构的二叉搜索树:

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-binary-search-trees-ii

若根节点为i,则左子树的节点为[1,…,i-1],右子树的节点为[i+1,…,n]。可递归的构建二叉搜索树。

#代码解释:好好看看看看!!
#1.特判,若n==0,返回[]
#2.定义生成树函数build_Trees(left,right),表示生成[left,...,right]的所有可能二叉搜索树:

    #若left>right,说明为空树,返回[None]
    #初始化所有可能的二叉搜索树列表all_trees=[]
    #遍历每一种可能的节点i,遍历区间[left,right+1):
        #所有可能的左子树列表left_trees=build_Trees(left,i−1)
        #所有可能的右子树列表right_trees=build_Trees(i+1,right)
        #组合所有的方式,遍历左子树列表l:遍历右子树列表r
            #建立当前树节点cur_tree=TreeNode(i)
            #将cur_tree左子树置为ll
            #将cur_tree右子树置为rr
            #将cur_tree加入树列表中
    #返回树列表all_trees

#3.返回build_Trees(1,n)
#作者:wu_yan_zu
#链接:https://leetcode-cn.com/problems/unique-binary-search-trees-ii/solution/di-gui-zhu-xing-jie-shi-python3-by-zhu_shi_fu/
class Solution(object):
    def generateTrees(self, n):
        """
        :type n: int
        :rtype: List[TreeNode]
        """
        def build_Trees(left,right):
            if left > right:
                return [None]
            all_trees = []
            for i in range(left, right+1):
                left_trees = build_Trees(left,i-1)
                right_trees = build_Trees(i+1, right)
                for l in left_trees:
                    for r in right_trees:
                        cur_tree = TreeNode(i)
                        cur_tree.left = l
                        cur_tree.right = r
                        all_trees.append(cur_tree)
            return all_trees
            
        if n == 0: return []
        return build_Trees(1,n)

对称二叉树

leetcode101 & offer28 判断是否是对称的二叉树

对称==镜像

[1,2,2,3,4,4,3]	对称
    1
   / \
  2   2
 / \ / \
3  4 4  3

[1,2,2,null,3,null,3]	不对称
    1
   / \
  2   2
   \   \
   3    3

带None的BFS,判断某层是否存在tmp==tmp[::-1]来看该层是否对称。
改进:若node为null,tmp.append(None)后,,不用找左右孩子了,直接跳去同层的下一个节点。

class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        if not root:
            return True
        curlevel = [root]
        while curlevel:
            tmp = []
            nextlevel = []
            for i in curlevel:
                # 增加一个节点是否为none的判断,则nextlevel.append的时候就不需要先判断再append了
                if not i: 
                    tmp.append(None)
                    continue
                tmp.append(i.val)
                nextlevel.append(i.left)
                nextlevel.append(i.right)
            if tmp != tmp[::-1]:
                return False
            curlevel = nextlevel
        return True

offer面试题27 输出二叉树的镜像

请完成一个函数,输入一个二叉树,该函数输出它的镜像。
BFS 没写成queue,没写成pop(0)。左右孩子谁先入(后出)stack都可以!!
当stack.pop()某节点时,交换它的左右孩子(进行镜像操作)因为所有节点都入stack,所以所有节点都处理到了。

class Solution(object):
    def mirrorTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        if not root: return []
        stack = [root]
        while stack:
            node = stack.pop()
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)
                
            #交换node的左右孩子
            node.left, node.right = node.right, node.left
            
        return root

平衡二叉树

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

leetcode110 & offer55 判断是否是平衡的二叉树

题目:给定一个二叉树,判断它是否是高度平衡的二叉树。
用辅助函数helper递归做了。改天有时间再看非递归方法。
这个写法是抄得解析,超牛!自底向顶法。

解释代码:
helper()返回值:若子树平衡,返回以root为根的树的深度,若是子树不平衡,返回值为-1.
class Solution(object):
    def isBalanced(self, root):
        return self.helper(root)!=-1

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

树的子结构

offer26 判断树B是否是树A的子结构

B是A的子结构, 即 A中有出现和B相同的结构和节点值。

给定的树 A:

     3
    / \
   4   5
  / \
 1   2
 
给定的树 B:
   4 
  /
 1
返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

定义辅助函数isSubTree(a,b),递归。

class Solution(object):
    def isSubStructure(self, A, B):
        """
        :type A: TreeNode
        :type B: TreeNode
        :rtype: bool
        """
        def isSubTree(a,b):
            if not b:
                return True
            elif not a:
                return False
            elif a.val == b.val:
                return isSubTree(a.left, b.left) and isSubTree(a.right, b.right)
            else:
                return False

        if not B or not A:
            return False
        return isSubTree(A, B) or self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B)

你可能感兴趣的:(刷题)