[LeetCode]199. 二叉树的右视图

题目

给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

示例:

输入: [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
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值