文章目录
- 树
- 二叉树
- 树的遍历
- 深度优先搜索
- 66 · 二叉树的前序遍历
- 67 · 二叉树的中序遍历
- 68 · 二叉树的后序遍历
- 递归
- 递归三要素
- 366 · 斐波纳契数列
- 递归的复杂度
- 481 · 二叉树叶子节点之和
- 97 · 二叉树的最大深度
树
树有层次关系,非线性的。线性就是一维的,而树有层次,不是一维的。
链表的head节点可以代表整个链表,二叉树也是一样的,当我们知道了根节点后,我们就知道了整个二叉树。所以根节点就是二叉树的代表。我们做题的时候,给定二叉树,也是给一个根节点。
二叉树
树的遍历
深度优先搜索
递归不是算法,而是一种程序的写法。应用这种程序写法的算法有枚举法、贪心法、动态规划、分治法。
所有递归都能转成非递归,递归只是一种程序写法,所以如果你能用优雅的递归写出代码,就用递归。
66 · 二叉树的前序遍历
给出一棵二叉树,返回其节点值的前序遍历。
一开始没想到用self.res来再两个函数中进行调用。
"""
Definition of TreeNode:
class TreeNode:
def __init__(self, val):
self.val = val
self.left, self.right = None, None
"""
class Solution:
"""
@param root: A Tree
@return: Preorder in ArrayList which contains node values.
"""
def preorderTraversal(self, root):
# write your code here
self.res = []
self.traversal(root)
return self.res
def traversal(self, root):
if root is None: return []
self.res.append(root.val)
self.traversal(root.left)
self.traversal(root.right)
67 · 二叉树的中序遍历
"""
Definition of TreeNode:
class TreeNode:
def __init__(self, val):
self.val = val
self.left, self.right = None, None
"""
class Solution:
"""
@param root: A Tree
@return: Inorder in ArrayList which contains node values.
"""
def inorderTraversal(self, root):
# write your code here
self.res = []
self.dfs(root)
return self.res
def dfs(self, root):
if not root: return
self.dfs(root.left)
self.res.append(root.val)
self.dfs(root.right)
68 · 二叉树的后序遍历
"""
Definition of TreeNode:
class TreeNode:
def __init__(self, val):
self.val = val
self.left, self.right = None, None
"""
class Solution:
"""
@param root: A Tree
@return: Postorder in ArrayList which contains node values.
"""
def postorderTraversal(self, root):
# write your code here
self.res = []
self.dfs(root)
return self.res
def dfs(self, root):
if not root: return
self.dfs(root.left)
self.dfs(root.right)
self.res.append(root.val)
递归
递归在数据结构上就是套娃,在算法上就是自己调用自己。
当我们学习数据结构的时候,我们主要是看它能存储什么样的数据,它有什么样的结构,以及它支持什么操作。
遍历就是一种操作,它是从头到尾把数据看一遍。如果一个数据结构无法遍历,那么它的很多其他操作也就无法执行。
递归三要素
366 · 斐波纳契数列
查找斐波纳契数列中第 N 个数。
所谓的斐波纳契数列是指:
前2个数是 0 和 1 。
第 i 个数是第 i-1 个数和第i-2 个数的和。
斐波纳契数列的前10个数字是:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34 …
def fibonacci(self, n):
# write your code here
if n == 1 or n == 2: return n - 1
return self.fibonacci(n - 1) + self.fibonacci(n - 2)
时间复杂度是2的n次方,所以不行。时间太大了。所以需要用递推。
def fibonacci(self, n):
# write your code here
res = [0, 1]
for i in range(2, n):
res.append(res[i - 1] + res[i - 2])
return res[n - 1]
下面是官方答案:
def fibonacci(self, n):
a = 0
b = 1
for i in range(n - 1):
a, b = b, a + b
return a
递归的复杂度
为什么深度优先搜索的空间复杂度是树的深度h,而且h又介于logn和n之间。当树的结构是满二叉树的时候,那么h=log(n+1),当树是极度不平衡的,比如所有节点只有左节点,那么这个树的高度h=n。所以一般情况下,h是介于log(n)~n之间的。
481 · 二叉树叶子节点之和
计算二叉树的叶子节点之和
"""
Definition of TreeNode:
class TreeNode:
def __init__(self, val):
self.val = val
self.left, self.right = None, None
"""
class Solution:
"""
@param root: the root of the binary tree
@return: An integer
"""
def leafSum(self, root):
# write your code here
self.leaf_sum = []
self.recursive(root)
return sum(self.leaf_sum)
def recursive(self, root):
if root is None: return
elif root.left is None and root.right is None:
self.leaf_sum.append(root.val)
self.recursive(root.left)
self.recursive(root.right)
下面是官方答案,我下次也有dfs这个函数名,多帅哦。还能传参数p。
class Solution:
# @param {TreeNode} root the root of the binary tree
# @return {int} an integer
def leafSum(self, root):
# Write your code here
p = []
self.dfs(root, p)
return sum(p)
def dfs(self, root, p):
if root is None:
return
if root.left is None and root.right is None:
p.append(root.val)
self.dfs(root.left, p)
self.dfs(root.right, p)
97 · 二叉树的最大深度
给定一个二叉树,找出其最大深度。
最大深度是从根节点到叶节点的最长路径的节点数。
想了半天没想出来,想起来用BFS的做法,但是看了老师的讲解,觉得好清晰。每一个点都带着自己的深度即可。太妙了。
"""
Definition of TreeNode:
class TreeNode:
def __init__(self, val):
self.val = val
self.left, self.right = None, None
"""
class Solution:
"""
@param root: The root of binary tree.
@return: An integer
"""
def maxDepth(self, root):
# write your code here
self.res = 0
self.dfs(root, 1)
return self.res
def dfs(self, root, depth):
if not root: return
self.res = max(self.res, depth)
self.dfs(root.left, depth + 1)
self.dfs(root.right, depth + 1)
看了老师的官方答案,绝了。。。。。
class Solution:
"""
@param root: The root of binary tree.
@return: An integer
"""
def maxDepth(self, root):
if root is None:
return 0
leftDepth = self.maxDepth(root.left)
rightDepth = self.maxDepth(root.right)
return max(leftDepth, rightDepth) + 1