题目
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例:
输入: [1,2,3,null,5,null,4]
输出: [1, 3, 4]
解释:
1 <---
/ \
2 3 <---
\ \
5 4 <---
解题思路
解法一:广度优先遍历
对二叉树进行层次遍历,而二叉树的层次遍历可以用广度优先搜索实现。那么对于每层来说,最右边的结点一定是最后被遍历到的,每次保存该层的最后一个节点即可。
复杂度分析:
时间复杂度: O(N),每个节点都入队出队了1次。
空间复杂度: O(N),使用了额外的队列空间。
解法二:深度优先遍历
按照 「根结点 -> 右子树 -> 左子树」 的顺序访问,就可以保证每层都是最先访问最右边的节点。(与先序遍历 「根结点 -> 左子树 -> 右子树」 正好相反,先序遍历每层最先访问的是最左边的节点)
注意:
1)递归法首先遍历右子树,再遍历左子树。
2)迭代法,用到了栈,由于栈是先进后出,所以栈顶元素先出栈,所以需要左子树先入栈,再右子树入栈。
复杂度分析:
时间复杂度: O(N),每个节点都访问了 1 次。
空间复杂度: O(N),因为这不是一棵平衡二叉树,二叉树的深度最少是 logN, 最坏的情况下会退化成一条链表,深度就是 N,因此递归时使用的栈空间是 O(N)的。
代码
解法一:广度优先遍历
代码1:从左向右遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
from collections import deque
class Solution:
def rightSideView(self, root: TreeNode) -> List[int]:
res = []
if not root:
return res
#queue = deque()
#queue.append(root)
queue = deque([root])
while queue:
size = len(queue)
for i in range(size): # 弹出本层的所有节点
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
if i == size-1: # 本层最后一个节点
res.append(node.val)
return res
代码2:从右向左遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
from collections import deque
class Solution:
def rightSideView(self, root: TreeNode) -> List[int]:
res = []
if not root:
return res
#queue = deque()
#queue.append(root)
queue = deque([root])
while queue:
size = len(queue)
for i in range(size): # 弹出本层的所有节点
node = queue.popleft()
if i == 0:
res.append(node.val)
if node.right:
queue.append(node.right)
if node.left:
queue.append(node.left)
return res
解法二:深度优先遍历
代码1:递归法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def __init__(self):
self.res = []
def dfs(self, node, depth):
if not node:
return
if depth>len(self.res):
self.res.append(node.val)
self.dfs(node.right, depth+1)
self.dfs(node.left, depth+1)
def rightSideView(self, root: TreeNode) -> List[int]:
self.dfs(root, 1)
return self.res
# 也可以这么写
# class Solution:
# def dfs(self, node, depth, res):
# if not node:
# return
# if depth>len(res):
# res.append(node.val)
# self.dfs(node.right, depth+1, res)
# self.dfs(node.left, depth+1, res)
# def rightSideView(self, root: TreeNode) -> List[int]:
# res = []
# self.dfs(root, 1, res)
# return res
代码2:迭代法(利用栈)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def rightSideView(self, root: TreeNode) -> List[int]:
res = []
if not root:
return res
stack = [(root,1)]
while stack:
node, depth = stack.pop() # 栈顶元素出栈
if depth>len(res):
res.append(node.val)
if node.left:
stack.append((node.left, depth+1))
if node.right:
stack.append((node.right, depth+1))
return res