leetcode 98,96,95,101,offer28,offer27,110,offer55,offer26
二叉搜索树
二叉搜索树具有如下特征:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
leetcode98 验证二叉搜索树
题目:给定一个二叉树,判断其是否是一个有效的二叉搜索树。
中序遍历,若单增,则是有效的二叉搜索树。
特例:空树为True。
不用全部遍历之后再判断,可以设置初始比较值为负无穷: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)