94. Binary Tree Inorder Traversal
题目解释:给定一颗二叉树,求其中序遍历的结果
Example:
Input: [1,null,2,3]
1
\
2
/
3
Output: [1,3,2]
这一题对于我们来说可以说是非常简单的了,但是为什么还要写出来呢?当然是面试的时候问到了,请直接手撕代码,中序遍历非递归。嗯,开始吧:
题目分析:我们首先是求二叉树中序遍历的时候,为了表示我们的诚意(实际是为了避免我们的尴尬),那么还是直接手写一个递归的吧:
class Solution:
def inorderTraversal(self, root: TreeNode):
"""
采用递归的方式去解决
:param root:
:return:
"""
res=[]
def inorder(root,res):
if root:
inorder(root.left,res)
res.append(root.val)
inorder(root.right,res)
inorder(root,res)
return res
好了好了,基本的代码已经写出来了,那么采用非递归应该怎么写呢?递归和非递归之间仅仅是相差一个栈,那么可以采用一个栈,然后再进行相关的操作,下面直接给出非递归遍历的代码(记得手撕一遍.....):
def inorderTraversal_iterable(self, root: TreeNode):
"""
采用非递归的方式来解决
:param root:
:return:
"""
if not root:
return []
stack =[]
output = []
while stack or root:
if root:
stack.append(root)
root = root.left
else:
node = stack.pop()
output.append(node.val)
root = node.right
return output
嗯,很重要,自己再次手撕了一遍.....
96. Unique Binary Search Trees
题目解释:给定一个数字n,组成一个list=[1,2,....n],判断这个list可以组成多少个不同的二叉排序树
Example:
Input: 3
Output: 5
Explanation:
Given n = 3, there are a total of 5 unique BST's:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
题目分析:我觉得很熟悉的一道题,想当初在考研的时候,直接就是手写出答案,那个速度叫一个快呀(好吧,不吹牛皮了.....),至少写出两种方式吧,一种是前人已经总结好的内容,另外一种是根据二叉排序树的特点来做题
方法1:卡特兰数
根据前人总结的内容来解题,那么就直接给出卡特兰数得到计算公式啦:
接下来就是直接计算就可以了:
def numTrees(self, n):
# 采用卡特兰数解决
return math.factorial(2 * n) / (math.factorial(n) * math.factorial(n + 1))
方法2:动态规划
首先我们可以分析一下,什么是二叉排序树:它或者是一棵空树,或者是具有下列性质的二叉树:
(1)若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(2)它的左、右子树也分别为二叉排序树。
若F(n)表示[1...n]能够构成的不同BST的数量,那么:
1、特殊情况,如果结点数为0,即n=0,为空树,F(0)=1;
2、如果结点数为1,即n=1,F(1)=1;
3、如果结点数为2,即n=2,F(2)=2;
4、对于n>=2的情况,事实上,1,2,..n都可以作为根节点,若i作为根节点,根据BST的性质,左子树不为空时(左子树为空,只能是i=1),左子树的所有节点必须小于根节点,即[1,i-1]必须位于左子树,同时,右子数节点必须值必须大于根节点值,则[i+1,n]必须位于右子树;
5、如上分析,对于[1,n],n>=2的情况,既然[1,n]每一个值都可以作为根节点,那我们需要遍历所有情况,时间复杂度为O(n),对于任何一种情况:根节点为i,则[1,i-1]为左子树,[i+1,n]为右子树,左子树有能够构成不同的BST的数量为:F(i-1),右子树能够构成的不同BST的数量为F(n-i);
左右植树相互独立,那么:F(n)=F(i-1)*F(n-i),i属于[1,n],i有n种情况,须完全遍历
def numTrees1(self, n):
"""
:param n:
:return:
"""
# (n+1)个开销单元,res最终是某个节点的情况数
res = [0] * (n + 1)
res[0] = 1
for i in range(1, n + 1):
# 后面需要做range运算主要是因为构成二叉树的结点情况不同导致
for j in range(i):
res[i] += res[j] * res[i - 1 - j]
return res[n]
总结
天气很美好呀,但是春天来了,很困.......