654. 最大二叉树 - 力扣(LeetCode)
一开始的代码版本如下所示
python
# 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 constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
if len(nums) == 0:
return None
max_num = max(nums)
max_index = nums.index(max_num)
root = TreeNode(val=max_num)
root.left = self.constructMaximumBinaryTree(nums[:max_num])
root.right = self.constructMaximumBinaryTree(nums[max_num:])
return root
这里犯了个低级错误,递归调用的时候参数应该分别是nums[:max_index]以及nums[max_index+1:],需要把当前这个元素给略掉,修正后AC的代码如下
python
# 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 constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
if len(nums) == 0:
return None
max_num = max(nums)
max_index = nums.index(max_num)
root = TreeNode(val=max_num)
root.left = self.constructMaximumBinaryTree(nums[:max_index])
root.right = self.constructMaximumBinaryTree(nums[max_index+1:])
return root
617. 合并二叉树 - 力扣(LeetCode)
递归方法构造,使用递归三部曲依次分析
python
# 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 mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
if root1 == None and root2 == None:
return None
val1 = 0 if root1 == None else root1.val
val2 = 0 if root2 == None else root2.val
cur = TreeNode(val1+val2)
root1_left, root1_right = (None, None) if root1 == None else (root1.left, root1.right)
root2_left, root2_right = (None, None) if root2 == None else (root2.left, root2.right)
cur.left = self.mergeTrees(root1_left, root2_left)
cur.right = self.mergeTrees(root1_right, root2_right)
return cur
看了下参考代码,发现有两点可以优化:
- 如果有一个为空可以直接剪枝
- 可以不用新建结点而是直接修改root1结点
python
# 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 mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
# 递归终止条件:
# 但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None.
if not root1:
return root2
if not root2:
return root1
# 上面的递归终止条件保证了代码执行到这里root1, root2都非空.
root1.val += root2.val # 中
root1.left = self.mergeTrees(root1.left, root2.left) #左
root1.right = self.mergeTrees(root1.right, root2.right) # 右
return root1 # ⚠️ 注意: 本题我们重复使用了题目给出的节点而不是创建新节点. 节省时间, 空间.
700. 二叉搜索树中的搜索 - 力扣(LeetCode)
根据二叉搜索树性质可得
python
# 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 searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if root == None:
return None
if root.val == val:
return root
elif root.val > val:
return self.searchBST(root.left, val)
else:
return self.searchBST(root.right, val)
98. 验证二叉搜索树 - 力扣(LeetCode)
利用二叉树特性,进行中序遍历,在遍历过程中判断结点的值是否是递增的,并且加入了一些剪枝降低某些情况的时间复杂度
python
# 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 isValidBST(self, root: Optional[TreeNode]) -> bool:
last_num = float('-inf')
def traversal(cur):
nonlocal last_num
if cur == None:
return True
left_res = traversal(cur.left)
if not left_res:
return False
if last_num >= cur.val:
return False
last_num = cur.val
right_res = traversal(cur.right)
if not right_res:
return False
return True
return traversal(root)
GPT4对于上面代码给出了一点建议,即在判断None的时候使用is而不是==
is None
和== None
在大多数情况下都能得到相同的结果,但是它们的检查机制是不同的。
is None
是检查对象的身份,也就是说它检查两个引用是否指向内存中的同一个对象。在Python中,None
是一个单例对象,也就是说在内存中只有一个None
。因此,is None
就是检查一个对象是否就是这个特定的None
对象。
== None
是检查对象的值,也就是说它检查两个对象的值是否相等。对于None
来说,这通常和is None
得到相同的结果。但是,如果一个对象重写了__eq__()
方法来改变==
的行为,那么== None
可能会得到不同的结果。因此,如果你想要检查一个对象是否为
None
,那么应该使用is None
,因为这样可以保证无论__eq__()
如何被重写,你都可以得到正确的结果。这就是
is None
和== None
的主要区别。在Python社区,通常推荐使用is None
和is not None
来检查一个对象是否为None
。
总结
- 递归中记得考虑剪枝来降低某些情况下的时间复杂度
- 在python中,判断是否为None推荐用is和is not