654.最大二叉树
1. 第一想法
当前数组nums中最大值的位置即为中序遍历的根节点位置。
整体相当于将数组看作中序遍历的序列数组, 只不过在找中序遍历序列的根节点时:
- 不是通过后序遍历或前序遍历的首尾元素节点位置来判断;
- 而是通过对整个数组求最大值来判断。 其余的做法基本一致。 如何找到一个数组的最大值,我通常的做法是:
- 设置一个键值对
<key, value>; - 当找到比key更大的元素时,更新这个键值对,其中键为最大元素,值为该元素的位置。 遍历整个数组,就可以找到该数组的最大值的位置。
# 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_loc = [-1, -1]
for idx in range(len(nums)):
if nums[idx] > max_loc[0]:
max_loc[0] = nums[idx]
max_loc[1] = idx
max_idx = max_loc[1]
left_child = self.constructMaximumBinaryTree(
nums=nums[:max_idx]
)
right_child = self.constructMaximumBinaryTree(
nums=nums[max_idx + 1:]
)
root = TreeNode(
val=max_loc[0],
left=left_child,
right=right_child
)
return root
2. 学习时长
15分钟。
617.合并二叉树
1. 第一想法
同样要遍历一颗二叉树,只不过遇到的终止条件,不是Root为空,而是两个Root都为空。 如果只有一个Root为空,另一个Root不为空,那么这里应该有一个节点。 如果两个Root同时不为空,那么我们应该将他们两个加起来。
# 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 (not root1) and (not root2):
return None
if root1 and (not root2):
return root1
if (not root1) and root2:
return root2
left_child = self.mergeTrees(
root1=root1.left,
root2=root2.left
)
right_child = self.mergeTrees(
root1=root1.right,
root2=root2.right
)
root = TreeNode(
val=root1.val + root2.val,
left=left_child,
right=right_child
)
return root
2. 读文档
文档链接 递归法肯定没有问题,迭代法我还没做,有机会再做迭代法。
3. 学习时长
23分钟。
700.二叉搜索树中的搜索
1. 第一想法
这道题也非常的简单,根据二叉树搜索数的基本特性就可以解。 如果当前节点的值小于我们要找的值,那我们就应该向右子树递归。 反之,我们应该向左子树递归。 如果当前根节点为空,那么说明没有找到。 如果当前根节点和值匹配,那么说明找到了。
# 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 not root:
return None
else:
if root.val == val:
return root
if root.val < val:
return self.searchBST(
root=root.right,
val=val
)
if root.val > val:
return self.searchBST(
root=root.left,
val=val
)
2. 实现上的困难
如果我们不写左右子树调用函数后的两个return,返回的就是None, 因为虽然上一层返回了,但是也只是返回到这一层的函数中,并没作为最后的结果返回,所以要逐层返回。
3. 学习时长
40分钟(找了半天bug)
98.验证二叉搜索树
1. 第一想法
直接搞个中序遍历,把遍历的结果用一个list存起来。 最后遍历整个list,检验单调性即可。
# 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 __init__(self):
self.list = []
def dfs(self, root):
if not root:
return
else:
node_stack = [root]
while node_stack:
node = node_stack.pop()
if (not node.left) and (not node.right):
self.list.append(node.val)
continue
if node.right:
node_stack.append(node.right)
node_stack.append(
TreeNode(
val=node.val
)
)
if node.left:
node_stack.append(node.left)
def isValidBST(self, root: Optional[TreeNode]) -> bool:
self.dfs(root)
for idx in range(len(self.list) - 1):
if self.list[idx] >= self.list[idx + 1]:
return False
return True
2. 实现过程中遇到的困难
- 因为中序遍历后后序遍历,stack都会再无条件加一遍砍掉左右子树的root到right和left之间,所以如果是叶子节点,加完list后就应该skip这次循环,如果不skip,会再把这个叶子节点加进去,这样就死循环了。
- 二叉搜索树是严格单调递增的,不存在相等元素的情况。
3. 看文档
文档链接 和我想的一样。
学习时长
30分钟。