【力扣hot100】刷题笔记Day13

前言

  • 元宵节快乐 ~ 周六在图书馆快乐刷题!继续二叉树🍴

543. 二叉树的直径 - 力扣(LeetCode)

  • 递归后序

    • class Solution:
          def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
              self.res = 0  # 记录最长路径
              # 递归求最大深度
              def depth(node):
                  if not node:
                      return 0
                  l = depth(node.left)   # 左子树最大深度
                  r = depth(node.right)  # 右子树最大深度
                  self.res = max(self.res, l + r)  # 两边深度相加就是最长路径
                  return max(l, r) + 1  # 返回当前最大深度
              depth(root)
              return self.res

108. 将有序数组转换为二叉搜索树 - 力扣(LeetCode)

  • 递归前序

    • class Solution:
          def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
              def helper(left, right):
                  if left > right: return     # left == right也可以返回一个结点
                  mid = (left + right) // 2
                  root = TreeNode(nums[mid])         # 构造根节点
                  root.left = helper(left, mid-1)    # 比根节点小的为左子树
                  root.right = helper(mid+1, right)  # 比根节点大的为右子树
                  return root
              return helper(0, len(nums)-1)

 98. 验证二叉搜索树 - 力扣(LeetCode)

  • 递归BST

    • 容易忽略上下界问题,详看题解
    • class Solution:
          def isValidBST(self, root: Optional[TreeNode]) -> bool:
              # 递归判断当前结点的值是否在上下界内
              def helper(node, minVal, maxVal):
                  if not node:
                      return True
                  # 每个节点如果超过这个范围,直接返回false
                  if node.val >= maxVal or node.val <= minVal:
                      return False
                  # 左子树范围的最小值是minVal,最大值是当前节点的值,因为左子树的值要比当前节点小
                  l = helper(node.left, minVal, node.val)
                  # 右子树范围的最大值是maxVal,最小值是当前节点的值,因为右子树的值要比当前节点大
                  r = helper(node.right, node.val, maxVal)
                  return l and r
              # 初始上下界无限大,python用浮点数表示整数最大最小
              return helper(root, -float('inf'), float('inf'))  
  •  递归中序

    • class Solution:
          # def __init__(self):
          #     self.pre = None  # 公共变量
          
          def isValidBST(self, root: Optional[TreeNode]) -> bool:
              self.pre = None  # 私有变量,记录上一个结点
              def helper(root):
                  if not root: return True
                  l = helper(root.left)   # 左
                  if self.pre and self.pre.val >= root.val:
                      return False        # 中
                  self.pre = root
                  r = helper(root.right)  # 右
                  return l and r
              return helper(root)
  • 迭代中序

    • class Solution:
          def isValidBST(self, root: Optional[TreeNode]) -> bool:
              if not root:
                  return True
              st = []
              pre = -float('inf')
              while st or root:
                  while root:
                      st.append(root)
                      root = root.left
                  temp = st.pop()
                  if temp.val <= pre:
                      return False
                  pre = temp.val
                  root = temp.right
              return True

230. 二叉搜索树中第K小的元素 - 力扣(LeetCode)

  • 迭代中序

    • class Solution:
          def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
              st = []
              while st or root:
                  while root:
                      st.append(root)
                      root = root.left
                  temp = st.pop()
                  k -= 1
                  if k == 0: 
                      return temp.val  # 遍历到第k个结点
                  root = temp.right
  • 优化查找

    • # 扩展TreeNode
      class TreeNode:
          def __init__(self, val=0, left=None, right=None):
              self.val = val
              self.left = left
              self.right = right
              self.node_num = 0  # 以该结点为根结点的子树的结点数
      
      # 构造可供查找的MyBst类
      class MyBst:
          def __init__(self, root: TreeNode):
              self.root = root
              self._count_node_num(root)  # 初始化时计算每个结点为根结点的子树的结点数
      
          def kth_smallest(self, k: int):
              node = self.root
              while node:
                  left = node.left.node_num if node.left else 0  # 获取左子树的结点数
                  if left < k - 1:
                      node = node.right  # 移动到右子树查找
                      k -= left + 1  # 更新 k 值
                  elif left == k - 1:
                      return node.val  # 当前结点即为第 k 小的结点
                  else:
                      node = node.left  # 移动到左子树查找
      
          def _count_node_num(self, node) -> int:
              if not node:
                  return 0
              # 递归计算以当前结点为根结点的子树的结点数
              node.node_num = 1 + self._count_node_num(node.left) + self._count_node_num(node.right)
              return node.node_num  # 返回以当前结点为根结点的子树的结点数
      
      class Solution:
          def kthSmallest(self, root: TreeNode, k: int) -> int:
              bst = MyBst(root)
              return bst.kth_smallest(k)  # 调用 MyBst 类的方法来找出第 k 小的结点的值

199. 二叉树的右视图 - 力扣(LeetCode)

  • 迭代层序BFS

    • class Solution:
          def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
              if not root: return []
              res = []
              q = deque()
              q.append(root)
              while q:
                  n = len(q)  # 先存长度以防变化
                  for i in range(n):
                      cur = q.popleft()
                      if cur.left: q.append(cur.left)
                      if cur.right: q.append(cur.right)
                      if i == n - 1:  # 本层最后一个结点
                          res.append(cur.val)
              return res
  • 递归逆先序DFS

    • # 思路类似【层序遍历】的 DFS递归
      class Solution:
          def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
              self.res = []
              # 传入层当前深度
              def dfs(root, depth):
                  if not root: return
                  if depth == len(self.res):
                      self.res.append(root.val)  # 中
                  dfs(root.right, depth + 1)     # 右
                  dfs(root.left, depth + 1)      # 左
              dfs(root, 0)
              return self.res

后言

  • 刷简单的二叉树题就是爽,递归的代码简短可以一次AC,还有精力去理解别的解法!多亏了之前刷代码随想录打的基础,感觉多刷一两次就可以看到就写出来了!刷二叉树信心MAX

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值