Leetcode 二叉树 3

题号直达: 102 二叉树的层序遍历 | 108 将有序数组转换为二叉搜索树

LeetCode 102. 二叉树的层序遍历 ↑

题目

给你二叉树的根节点 root,返回其节点值的 层序遍历。(即逐层地,从左到右访问所有节点)。

提示

  • 树中节点数目在范围 [0, 2000] 内
  • -1000 ≤ Node.val ≤ 1000

代码(Python)

from collections import deque

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: Optional[TreeNode]
        :rtype: List[List[int]]
        """
        if not root:
            return []
        temp = deque()
        temp.append(root)
        ans = []
        while temp:
            N = len(temp)
            ans_temp = []
            for i in range(N):
                p = temp.popleft()
                ans_temp.append(p.val)
                if p.left:
                    temp.append(p.left)
                if p.right:
                    temp.append(p.right)
            ans.append(ans_temp)
        return ans

思路解析

  • BFS + 按层分组:用 deque 做队列,每次处理当前层全部结点:先记录本层宽度 N = len(temp),再连续 popleft 恰好 N 次,把这层的值写入 ans_temp,同时把每个结点的左右孩子(若存在)加入队尾,供下一轮作为下一层处理。
  • 空树:root 为 None 时直接返回 []。
  • 为何要先取 N:队列里在「处理本层」过程中会不断塞入下一层结点,若不在循环前固定本层个数,会把新入队的下一层结点误算进当前层。
  • 复杂度:每个结点入队、出队各一次,时间 O(n),n 为结点数;队列最坏同时存约一层结点,空间最坏 O(n)(完全二叉树最后一层可达约 n/2)。

LeetCode 108. 将有序数组转换为二叉搜索树 ↑

题目

给你一个整数数组 nums,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 的二叉搜索树。

提示

  • 1 ≤ nums.length ≤ 10^4
  • -10^4 ≤ nums[i] ≤ 10^4
  • nums 按 严格递增 顺序排列

代码(Python)解法一:分治(取中点为根)

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution(object):
    def sortedArrayToBST(self, nums):
        """
        :type nums: List[int]
        :rtype: Optional[TreeNode]
        """
        return self.helper(nums, 0, len(nums) - 1)

    def helper(self, nums, left, right):
        if left > right:
            return None

        mid = (left + right) // 2

        root = TreeNode(nums[mid])
        root.left = self.helper(nums, left, mid - 1)
        root.right = self.helper(nums, mid + 1, right)
        return root

思路解析(解法一)

  • BST + 平衡:中序遍历 BST 得到升序序列;反过来,有序数组的中点作根,则左半段均小于根、右半段均大于根,天然满足 BST;左右子树递归时仍取各自区间中点作子树根,使左右规模至多差 1,树高平衡。
  • helper(nums, left, right):构建下标区间 [left, right] 对应的平衡 BST;left > right 时为空,返回 None。
  • 中点:mid = (left + right) // 2 作为当前子树根的值,左子树为 helper(left, mid-1),右子树为 helper(mid+1, right)。
  • 复杂度:每个元素参与一次建结点,时间 O(n);递归栈深度 O(log n)(平衡时),最坏链状递归 O(n)。

代码(Python)解法二:分治(上取整中点)

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution(object):
    def sortedArrayToBST(self, nums):
        """
        :type nums: List[int]
        :rtype: Optional[TreeNode]
        """
        return self.helper(nums, 0, len(nums) - 1)

    def helper(self, nums, left, right):
        if left > right:
            return None

        mid = (left + right + 1) // 2

        root = TreeNode(nums[mid])
        root.left = self.helper(nums, left, mid - 1)
        root.right = self.helper(nums, mid + 1, right)
        return root

思路解析(解法二)

  • 与解法一的关系:同样是区间分治、选「中点」作根,左子区间建左子树、右子区间建右子树;仅 中点下标 的取法不同。
  • mid = (left + right + 1) // 2:在区间长度为偶数时,Python 的 // 会向下取整;若写 (left + right) // 2 更偏向左侧中点,而 (left + right + 1) // 2 等价于对长度折半上取整时选右侧中点,使根略偏右,得到的 BST 形态与解法一可能不同,但仍是合法 BST 且保持 高度平衡。
  • 选用:两种写法均可通过本题;若希望与「左偏中点」的常见题解区分,或避免某侧区间长期多 1 个元素,可按习惯选择其一。
posted @ 2026-10-11 23:50  Phier  阅读(1)  评论(0)    收藏  举报