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^4nums按 严格递增 顺序排列
代码(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 个元素,可按习惯选择其一。

浙公网安备 33010602011771号