1. 问题描述:
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例:
输入: [1,2,3,null,5,null,4]
输出: [1, 3, 4]
解释:
1 <---
/ \
2 3 <---
\ \
5 4 <---
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-right-side-view
2. 思路分析:
① 因为是关于二叉树的题目,所以应该是可以使用深度优先搜索(dfs)或者是广度优先搜索(bfs)解决的,分析题目可以知道我们最终的目的是找出每一层节点中的最右边的节点,而每一层最右边的节点恰恰满足了二叉树的右视图的特点,bfs解决的话可以按照顺序访问每一层的节点,所以应该比dfs搜索处理会更简单一点,所以我们可以使用bfs,为每一层节点添加一个深度这样bfs按照每一层节点的顺序访问每一层最后访问的节点肯定是最右的,由于使用的是python语言,我们可以使用collections.defaultdict(int)声明一个双端队列,队列的元素类型为元组,元组的第一个值为当前的TreeNode类型,第二个值为当前节点的深度,当队列不为空的时候执行循环,弹出队列中最左边的节点,我们可以使用字典来标记每一层节点的值这样每一层节点访问的时候后面访问的节点值就会将前面相同深度的节点值给覆盖掉从而可以记录当前深度最右边的节点,然后依次加入当前节点的左右节点即可(加入左右孩子节点的深度为弹出节点的深度加1),我感觉最重要的是要看出问题的本质是什么,最终我们要求解的是什么那么剩下来的就好办了
② 感觉python的元组真的挺方便的,有时候需要表示多个值映射到一个值的时候就很方便,比如映射二维坐标的位置等等
3. 代码如下:
import collections
from typing import List
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def bfs(self, root: TreeNode, res: List[int]):
if not root: return list()
queue = collections.deque()
queue.append((root, 0))
dic = collections.defaultdict(int)
while queue:
# 注意是popleft()而不是pop()方法,一开始的时候写错了导致调试了很久
poll = queue.popleft()
dic[poll[1]] = poll[0].val
if poll[0].left:
queue.append((poll[0].left, poll[1] + 1))
if poll[0].right:
queue.append((poll[0].right, poll[1] + 1))
# 将字典转换为列表
return list(dic.values())
def rightSideView(self, root: TreeNode) -> List[int]:
res = list()
return self.bfs(root, res)