本文已参与「新人创作礼」活动,一起开启掘金创作之路。
0️⃣python数据结构与算法学习路线
学习内容:
- 基本算法:枚举、排序、搜索、递归、分治、优先搜索、贪心、双指针、动态规划等…
- 数据结构:字符串(string)、列表(list)、元组(tuple)、字典(dictionary)、集合(set)、数组、队列、栈、树、图、堆等…
目录
leetcode-104
题目:
给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
输入:
给定二叉树 [3,9,20,null,null,15,7]
输出:
从下到上遍历的深度优先算法
程序:
递归方法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if root is None:
return 0
else:
left = self.maxDepth(root.left)
right = self.maxDepth(root.right)
return max(left,right)+1
出现的问题
- 调用自己是用self.maxDepth而不是直接maxDepth
- 使用类里面的方法是root.left而不是self.left
leetcode-110
题目:
给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
输入:
root = [3,9,20,null,null,15,7]
输出:true
程序:
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
def height(root: TreeNode) -> int:
if not root:
return 0 # 不能直接返回True 因为后面还有别的支线
return max(height(root.left), height(root.right)) + 1
if not root:
return True
return abs(height(root.left) - height(root.right)) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right)
# 返回Ture和False的时候不用if判断因为语句本身就返回Ture和False
# 类中调用自己函数的时候用self.函数名
leetcode-543
题目:
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
注意:两结点之间的路径长度是以它们之间边的数目表示。
输入:
给定二叉树 [3,9,20,null,null,15,7]
输出:
返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。
程序:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def diameterOfBinaryTree(self, root: TreeNode) -> int:
self.ans = 1
def deepth(root):
if root is None:
return 0
else:
right = deepth(root.right)
left = deepth(root.left)
self.ans = max(right+left+1,self.ans)
return max(left,right)+1# 不加1的话一直为1
deepth(root)#递归函数定义之后要调用
return self.ans-1#和多了一个
广度优先
先遍历根节点的所有孩子节点,再依次遍历每一个孩子节点的孩子节点(按层遍历)
def breadth_tree(tree):
lst = []
def traverse(node, p):
if node._left is not None:
lst.append(node._left)
if node._right is not None:
lst.append(node._right)
if p > (len(lst) -2):
return
else:
traverse(lst[p+1], p+1)
lst.append(tree._root)
traverse(tree._root, 0)
# 遍历结果就存在了lst表里
for node in lst:
print node._data
深度优先
DFS是从根节点出发,每次遍历它的左孩子节点,当遍历到叶子节点时候,回退一步返回到它的父亲节点,接着遍历父亲节点的其它孩子节点。如此重复,直到遍历完所有节点。
深度优先算法分为两步:
- 考虑怎么递归
- 递归中要做什么:
- 前序遍历
- 中序遍历
- 后序遍历
下面没有结点了就返回
问题:什么时候从上往下 什么时候 从下往上?
从下往上传最常见也最难
def depth_tree(tree):
lst = []
lst.append(tree._root)
while len(lst) > 0:
node = lst.pop()
print node._data
if node._right is not None:
lst.append(node._right)
if node._left is not None:
lst.append(node._left)
程序易错点
- 因为树的左右长度需要用递归方法,要单独定义函数
- 定义的递归函数要注意返回时候要+1,如果不+1求左右最大值始终是1,例如:max(left,right)+1
- 定义函数之后要记得调用
- 写在class下面的函数写递归要用self.deepth()
- 用self.ans定义,不能用ans定义