tasks for today:
1.226.翻转二叉树(递归优先掌握)
2.101对称二叉树(递归优先掌握)
3.104.二叉树的最大深度(递归优先掌握)
4.111.二叉树的最小深度(递归优先掌握)
-----------------------------------------------------------------------------------
1.226.翻转二叉树(递归优先掌握)
In this practice, still adhering to the 3-steps for recusive algorithm:
input&output -> end condition -> the work flow of each level in recursive algo
# 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 invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
def reverseTree(node):
if node is None:
return
leftchild = node.left
node.left = node.right
node.right = leftchild
reverseTree(node.left)
reverseTree(node.right)
reverseTree(root)
return root
Go version
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func invertTree(root *TreeNode) *TreeNode {
var reverseT func (node *TreeNode)
reverseT = func (node *TreeNode) {
if node == nil {
return
}
temp := node.Left
node.Left = node.Right
node.Right = temp
reverseT(node.Left)
reverseT(node.Right)
}
reverseT(root)
return root
}
note: in this practice, the traversal method is preorder
2.101对称二叉树(递归优先掌握)
the key for this practice is compare the inside nodes of two child trees and outside nodes of two child trees.
for the recursive function "compareLeftRight", three steps logic still apply to this practice.
# 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 isSymmetric(self, root: Optional[TreeNode]) -> bool:
def compareLeftRight(leftnode, rightnode):
# end condition
if leftnode is None and rightnode is not None:
return False
elif leftnode is not None and rightnode is None:
return False
elif leftnode is None and rightnode is None:
return True
elif leftnode.val != rightnode.val:
return False
# compare inside and outside
outside = compareLeftRight(leftnode.left, rightnode.right)
inside = compareLeftRight(leftnode.right, rightnode.left)
return outside and inside
if root is None:
return True
return compareLeftRight(root.left, root.right)
3.104.二叉树的最大深度(递归优先掌握)
binary tree depth: 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
In this practice, the bfs is a better choice, cause bfs is executed by level, so by going through all the levels, the number of levels can be calculated, which equals to the deepest depth of a binary tree
# 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: Optional[TreeNode]) -> int:
if root is None:
return 0
queueTree = collections.deque([root])
calcu = 0
while queueTree:
for _ in range(len(queueTree)):
cur = queueTree.popleft()
if cur.left:
queueTree.append(cur.left)
if cur.right:
queueTree.append(cur.right)
calcu += 1
return calcu
recursive: dfs can also be used
本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。
- 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
- 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)
而根节点的高度就是二叉树的最大深度,所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。
here is a postorder traversal version: 后序遍历(左右中)求根节点的高度,也就是二叉树的最大深度
# 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: Optional[TreeNode]) -> int:
def getdepth(node):
if node is None:
return 0
leftdepth = getdepth(node.left)
righdepth = getdepth(node.right)
depth = 1+ max(leftdepth, righdepth)
return depth
return getdepth(root)
4.111.二叉树的最小深度(递归优先掌握)
In this practice, bfs can also be used, similar with the deepest depth, in this practice, only a bot of modification is needed to realize the smallest depth. That is, when the node's left node and right node are both none, directly return current cumulated depth.
# 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 minDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
queueTree = collections.deque([root])
calcu = 0
while queueTree:
calcu += 1
for _ in range(len(queueTree)):
cur = queueTree.popleft()
if cur.left is None and cur.right is None:
return calcu
if cur.left:
queueTree.append(cur.left)
if cur.right:
queueTree.append(cur.right)
return calcu
similarly, dfs/recursive algo can alse work out.
But one thing needs to be noted is: it is not rightt to simply change max to min, because this will lead to error when the node only have one child node, either left or right, then this calculation will wrongly count as 1 + 0, which does not match to the case.
# 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 minDepth(self, root: Optional[TreeNode]) -> int:
def getdepth(node):
if node is None:
return 0
leftDepth = getdepth(node.left)
rightDepth = getdepth(node.right)
if node.left is None and node.right is not None:
return rightDepth + 1
if node.left is not None and node.right is None:
return leftDepth + 1
depth = 1 + min(leftDepth, rightDepth)
return depth
return getdepth(root)