打卡Day13
- 1.理論基礎
- 2.二叉樹的遞歸遍歷
- 3.二叉樹的迭代遍歷
- 3.二叉樹的統一迭代法
- 4.102.二叉樹的層序遍歷
- 擴展
- 107. 二叉樹的層序遍歷 II
- 199.二叉樹的右視圖
- 637.二叉樹的層平均值
- 429.N叉樹的層序遍歷
- 515.在每個樹行中找最大值
- 116.填充每個節點的下一個右側節點指針
- 117. 填充每個節點的下一個右側節點指針 II
- 104. 二叉樹的最大深度
- #111.二叉樹的最小深度
1.理論基礎
文檔講解: 代碼隨想錄
解題過程二叉樹有兩種主要形式:滿二叉樹和完全二叉樹。
(1)滿二叉樹:一棵二叉樹只有度為0的節點和度為2的節點,并且度為0的節點在同一層上。深度為 k 的滿二叉樹有 2^k - 1 個節點。
(2)完全二叉樹:除了最底層節點可能沒填滿外,其余每層節點數都達到最大值,并且最下面的節點都集中在該層最左邊的若干位置。若最底層為第 h(h >= 1) 層,則該層包含 1 ~ 2^(h -1) 。
之前優先級隊列其實是一個堆,堆是一顆完全二叉樹,同時保證父子節點的順序關系。
二叉搜索樹:是一個有序樹。
平衡二叉搜索樹:是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,并且左右兩個子樹都是一棵平衡二叉樹。
二叉樹的定義:
class TreeNode:def __init__(self, val, left = None, right = None):self.val = valself.left = leftself.right = right
2.二叉樹的遞歸遍歷
文檔講解: 代碼隨想錄
遞歸算法的三要素:
(1)確定遞歸函數的參數和返回值:確定哪些參數是遞歸的過程中需要處理的,那么就在遞歸函數里加上這個參數,并且還要明確每次遞歸的返回值是什么進而確定遞歸函數的返回類型。
(2)確定終止條件:如果遞歸沒有終止,操作系統的內存站必然會溢出。運行遞歸算法遇到棧溢出的錯誤,就是沒寫終止條件或者終止條件寫的不對。
(3)確定單層遞歸的邏輯:確定每一層遞歸需要處理的信息,在這里也就會重復調用自己來實現遞歸的過程。
以前序遍歷為例:
(1)確定遞歸函數的參數和返回值:參數為當前樹節點,返回值為空。我本來以為需要返回節點的數據,但在函數的內部直接將數據加入到列表中。
(2)終止條件:當遍歷的節點為空,直接return。
(3)確定單層遞歸的邏輯:先取中節點的數值,再取左節點,最后右節點。
題目鏈接:前序遍歷
class Solution(object):def preorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""res = []def dfs(node):if node is None:returnres.append(node.val)dfs(node.left)dfs(node.right)dfs(root)return res
題目鏈接:后序遍歷
class Solution(object):def postorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""res = []def dfs(node):if node is None:returndfs(node.left)dfs(node.right)res.append(node.val)dfs(root)return res
題目鏈接:中序遍歷
class Solution(object):def inorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""res = []def dfs(node):if node is None:return dfs(node.left)res.append(node.val)dfs(node.right)dfs(root)return res
3.二叉樹的迭代遍歷
文檔講解: 代碼隨想錄
題目鏈接:前序遍歷
class Solution(object):def preorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""if not root:return []#跟節點先入棧stack = [root]res = []while stack:node = stack.pop()#處理中節點res.append(node.val)#右孩子先入棧if node.right:stack.append(node.right)#左孩子入棧if node.left:stack.append(node.left)return res
題目鏈接:后序遍歷
class Solution(object):def postorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""if not root:return []stack = [root]res = []while stack:node = stack.pop()res.append(node.val)if node.left:stack.append(node.left)if node.right:stack.append(node.right)return res[::-1]
題目鏈接:中序遍歷
在中序遍歷中,處理元素和訪問元素的順序不一致,需要借助指針的遍歷來幫助訪問節點,棧用來處理節點上的元素。不能提前將根節點放入棧中,如果先放入的話,迭代處理會先訪問跟節點,而不是最左邊的葉子節點。
class Solution(object):def inorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""if not root:return []res = []stack = []cur = rootwhile cur or stack:#先迭代訪問最左邊的葉子節點if cur:stack.append(cur)cur = cur.leftelse:#此時cur = nullcur = stack.pop()res.append(cur.val)cur = cur.rightreturn res
3.二叉樹的統一迭代法
文檔講解: 代碼隨想錄
題目鏈接:前序遍歷
class Solution(object):def preorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""res = []stack = []if root:stack.append(root)while stack:node = stack.pop()if node != None:if node.right:stack.append(node.right)if node.left:stack.append(node.left)stack.append(node)stack.append(None)else:node = stack.pop()res.append(node.val)return res
題目鏈接:后序遍歷
class Solution(object):def postorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""res = []stack = []if root:stack.append(root)while stack:node = stack.pop()if node != None:stack.append(node)stack.append(None)if node.left:stack.append(node.left)if node.right:stack.append(node.right)else:node = stack.pop()res.append(node.val)return res
題目鏈接:中序遍歷
class Solution(object):def inorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""res = []stack = []if root:stack.append(root)while stack:node = stack.pop()if node != None:if node.right:stack.append(node.right)stack.append(node)stack.append(None)if node.left:stack.append(node.left)else:node = stack.pop()res.append(node.val)return res
4.102.二叉樹的層序遍歷
題目鏈接:102.二叉樹的層序遍歷
文檔講解: 代碼隨想錄
class Solution(object):def levelOrder(self, root):""":type root: TreeNode:rtype: List[List[int]]"""if not root:return []queue = collections.deque([root])res = []while queue:level = []for i in range(len(queue)):cur = queue.popleft()level.append(cur.val)if cur.left:queue.append(cur.left)if cur.right:queue.append(cur.right)res.append(level)return res
遞歸法:
class Solution(object):def levelOrder(self, root):""":type root: TreeNode:rtype: List[List[int]]"""if not root:return []levels = []def traverse(node, level):if not node:returnif len(levels) == level:levels.append([])levels[level].append(node.val)traverse(node.left, level + 1)traverse(node.right, level + 1)traverse(root, 0)return levels
擴展
107. 二叉樹的層序遍歷 II
題目鏈接:107
思路:在上題的基礎上,輸出的時候反轉一下順序。
class Solution(object):def levelOrderBottom(self, root):""":type root: TreeNode:rtype: List[List[int]]"""if not root:return []res = []queue = collections.deque([root])while queue:level = []for i in range(len(queue)):node = queue.popleft()level.append(node.val)if node.left:queue.append(node.left)if node.right:queue.append(node.right)res.append(level)return res[::-1]
199.二叉樹的右視圖
題目鏈接:199
一開始題目沒有理解好,以為是將每層元素從右往左組成列表輸出。題目要求的是只輸出每層最右邊元素組成的一維列表。
class Solution(object):def rightSideView(self, root):""":type root: TreeNode:rtype: List[int]"""if not root:return []res = []queue = collections.deque([root])while queue:#需要用變量存儲長度,因為下面會對隊列進行操作size = len(queue)for i in range(size):node = queue.popleft()if i == size - 1:res.append(node.val)if node.left:queue.append(node.left)if node.right:queue.append(node.right)return res
637.二叉樹的層平均值
題目鏈接:637
class Solution(object):def averageOfLevels(self, root):""":type root: TreeNode:rtype: List[float]"""if not root:return []queue = collections.deque([root])res = []while queue:summ = 0size = len(queue)for i in range(size):node = queue.popleft()summ += node.valif node.left:queue.append(node.left)if node.right:queue.append(node.right)res.append(round(summ / size, 4))return res
出現的問題:
將自己的代碼替換到python3中是可行的,感覺是數據類型有點問題,具體是什么問題不能確認,暫時沒有解決。
429.N叉樹的層序遍歷
題目鏈接:429
class Solution(object):def levelOrder(self, root):""":type root: Node:rtype: List[List[int]]"""if not root:return []res = []queue = collections.deque([root])while queue:level = []size = len(queue)for i in range(size):node = queue.popleft()level.append(node.val)#用for循環遍歷孩子節點for child in node.children:queue.append(child)res.append(level)return res
515.在每個樹行中找最大值
題目鏈接:515
class Solution(object):def largestValues(self, root):""":type root: TreeNode:rtype: List[int]"""if not root:return []queue = collections.deque([root])res = []while queue:size = len(queue)maxx = queue[0].val#可以使用maxx = float('-inf')初始化for i in range(size):node = queue.popleft()if node.val > maxx:maxx = node.valif node.left:queue.append(node.left)if node.right:queue.append(node.right)res.append(maxx)return res
116.填充每個節點的下一個右側節點指針
題目鏈接:116
class Solution(object):def connect(self, root):""":type root: Node:rtype: Node"""if not root:return rootqueue = collections.deque([root])while queue:size = len(queue)pre = Nonefor i in range(size):node = queue.popleft()if pre:pre.next = nodepre = nodeif node.left:queue.append(node.left)if node.right:queue.append(node.right)return root
117. 填充每個節點的下一個右側節點指針 II
題目鏈接:117
class Solution(object):def connect(self, root):""":type root: Node:rtype: Node"""if not root:return rootqueue = collections.deque([root])while queue:size = len(queue)pre = None for i in range(size):node = queue.popleft()if pre:pre.next = nodepre = nodeif node.left:queue.append(node.left)if node.right:queue.append(node.right)return root
104. 二叉樹的最大深度
題目鏈接:104
class Solution(object):def maxDepth(self, root):""":type root: TreeNode:rtype: int"""if not root:return 0queue = collections.deque([root])deep = 0while queue:size = len(queue)deep += 1for i in range(size):node = queue.popleft()if node.left:queue.append(node.left)if node.right:queue.append(node.right)return deep
#111.二叉樹的最小深度
題目鏈接:111
class Solution(object):def minDepth(self, root):""":type root: TreeNode:rtype: int"""if not root:return 0deep = 0queue = collections.deque([root])while queue:size = len(queue)deep += 1for i in range(size):node = queue.popleft()if not node.left and not node.right:return deepif node.left:queue.append(node.left)if node.right:queue.append(node.right)return deep