【代码随想录训练营】【Day 23】【二叉树-7】| Leetcode 530, 501, 236
需强化知识点
- 二叉搜索树:中序遍历 / 双指针(prev和cur)
- 递归三部曲:确定终止条件(一般是值为空) -> 确定单层递归逻辑
题目
530. 二叉搜索树的最小绝对差
- 常规解法:中序遍历得到数组,然后依次判断
- 双指针:迭代法后序遍历,双指针
# 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 getMinimumDifference(self, root: Optional[TreeNode]) -> int:
def traverse(root):
if not root:
return []
left = traverse(root.left)
right = traverse(root.right)
return left + [root.val] + right
node_list = traverse(root)
result = float('inf')
for i in range(len(node_list)):
if i > 0:
result = min(result, abs(node_list[i] - node_list[i-1]))
return result
# stack = []
# cur = root
# result = float('inf')
# pre = None
# while stack or cur:
# if cur:
# stack.append(cur)
# cur = cur.left
# else:
# cur = stack.pop()
# if pre:
# result = min(result, abs(pre.val - cur.val))
# pre = cur
# cur = cur.right
# return result
501. 二叉搜索树中的众数
- 常规:遍历过程利用字典记录次数(注意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:
# 二叉搜索树(BST)经典:中序遍历+双指针(prev和cur)
def __init__(self):
self.maxCount = 0
self.result = []
self.count = 0
self.prev = None
def traverse(self, cur):
if not cur:
return
self.traverse(cur.left)
if not self.prev:
self.count = 1
elif self.prev.val == cur.val:
self.count += 1
else:
self.count = 1
# 注意等于的情况不同
if self.count == self.maxCount:
self.result.append(cur.val)
if self.count > self.maxCount:
self.maxCount = self.count
# 这是一种在清空result
self.result = [cur.val]
self.prev = cur
self.traverse(cur.right)
def findMode(self, root: Optional[TreeNode]) -> List[int]:
self.traverse(root)
return self.result
# 注意要写成传参的写法,而不能在traverse新建一个字典 !!!
# def traverse(root, count_dict):
# if not root:
# return
# traverse(root.left, count_dict)
# count_dict[root.val] += 1
# traverse(root.right, count_dict)
# count_dict = collections.defaultdict(int)
# traverse(root, count_dict)
# max_value = max(count_dict.values())
# result = []
# for key, value in count_dict.items():
# if value == max_value:
# result.append(key)
# return result
236. 二叉树的最近公共祖先
- 代码随想录思路:
- 如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先
- 判断逻辑是 如果递归遍历遇到q,就将q返回,遇到p 就将p返回,那么如果 左右子树的返回值都不为空,说明此时的中节点,一定是q 和p 的最近祖先。
- 先用left和right接住左子树和右子树的返回值
- 如果left 和 right都不为空,说明此时root就是最近公共节点。这个比较好理解;如果left为空,right不为空,就返回right,说明目标节点是通过right返回的,反之依然。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if not root or root == p or root == q:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if left and right:
return root
elif left:
return left
elif right:
return right
else:
return None