一、力扣226.翻转二叉树
翻转一棵二叉树。
思路:
用层序遍历
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
if not root:
return None
queue = collections.deque([root])
while queue:
for i in range(len(queue)):
node = queue.popleft()
node.left, node.right = node.right, node.left
if node.left: queue.append(node.left)
if node.right: queue.append(node.right)
return root
递归(前序):
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
if not root:
return None
root.left, root.right = root.right, root.left
self.invertTree(root.left)
self.invertTree(root.right)
return root
递归(中序):
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
if not root:
return None
self.invertTree(root.left)
root.left, root.right = root.right, root.left
self.invertTree(root.left)
return root
递归(后序):
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
if not root:
return None
self.invertTree(root.left)
self.invertTree(root.left)
root.left, root.right = root.right, root.left
return root
二、101. 对称二叉树
给定一个二叉树,检查它是否是镜像对称的。
思路:
首先想清楚,判断对称二叉树要比较的是哪两个节点,要比较的可不是左右节点!
对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了其实我们要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。
那么如何比较呢?
比较的是两个子树的里侧和外侧的元素是否相等。如图所示:
那么遍历的顺序应该是什么样的呢?
本题遍历只能是“后序遍历”,因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等。
正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。
递归三部曲
1.确定递归函数的参数和返回值
因为我们要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数自然也是左子树节点和右子树节点。
返回值自然是bool类型。
代码如下:
bool compare(TreeNode* left, TreeNode* right)
2.确定终止条件
要比较两个节点数值相不相同,首先要把两个节点为空的情况弄清楚!否则后面比较数值的时候就会操作空指针了。
节点为空的情况有:(注意我们比较的其实不是左孩子和右孩子,所以如下我称之为左节点右节点)
- 左节点为空,右节点不为空,不对称,return false
- 左不为空,右为空,不对称 return false
- 左右都为空,对称,返回true
此时已经排除掉了节点为空的情况,那么剩下的就是左右节点不为空:
- 左右都不为空,比较节点数值,不相同就return false
此时左右节点不为空,且数值也不相同的情况我们也处理了。
3.确定单层递归的逻辑
此时才进入单层递归的逻辑,单层递归的逻辑就是处理 左右节点都不为空,且数值相同的情况。
- 比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。
- 比较内侧是否对称,传入左节点的右孩子,右节点的左孩子。
- 如果左右都对称就返回true ,有一侧不对称就返回false
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
if not root:
return True
return self.compare(root.left, root.right)
def compare(self, left, right):
#首先排除空节点的情况
if left == None and right != None: return False
elif left != None and right == None: return False
elif left == None and right == None: return True
#排除了空节点,再排除数值不相同的情况
elif left.val != right.val: return False
#此时就是:左右节点都不为空,且数值相同的情况
#此时才做递归,做下一层的判断
outside = self.compare(left.left, right.right) #左子树:左、 右子树:右
inside = self.compare(left.right, right.left) #左子树:右、 右子树:左
isSame = outside and inside #左子树:中、 右子树:中 (逻辑处理)
return isSame
三、104.二叉树的最大深度
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例: 给定二叉树 [3,9,20,null,null,15,7],
返回它的最大深度 3 。
思路:
递归后序
class Solution:
def maxdepth(self, root: treenode) -> int:
return self.getdepth(root)
def getdepth(self, node):
if not node:
return 0
leftheight = self.getdepth(node.left) #左
rightheight = self.getdepth(node.right) #右
height = 1 + max(leftheight, rightheight) #中
return height
层序遍历:
# 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 not root:
return 0
queue = collections.deque([root])
depth = 0
while queue:
size = len(queue)
depth += 1
for i in range(size):
cur = queue.popleft()
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
return depth
四、111.二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
返回它的最小深度 2.
思路:
递归法
class Solution:
def getDepth(self, node):
if node is None:
return 0
leftDepth = self.getDepth(node.left) # 左
rightDepth = self.getDepth(node.right) # 右
# 当一个左子树为空,右不为空,这时并不是最低点
if node.left is None and node.right is not None:
return 1 + rightDepth
# 当一个右子树为空,左不为空,这时并不是最低点
if node.left is not None and node.right is None:
return 1 + leftDepth
result = 1 + min(leftDepth, rightDepth)
return result
def minDepth(self, root):
return self.getDepth(root)
层序遍历:
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
queue = collections.deque([root])
depth = 0
while queue:
depth += 1
for i in range(len(queue)):
cur = queue.popleft()
if not cur.left and not cur.right:
return depth
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
return depth