每日一练:二叉树的右视图

199. 二叉树的右视图 - 力扣(LeetCode)

一、题目要求

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

示例 1:

输入: [1,2,3,null,5,null,4]
输出: [1,3,4]

示例 2:

输入: [1,null,3]
输出: [1,3]

示例 3:

输入: []
输出: []

提示:

  • 二叉树的节点个数的范围是 [0,100]
  • -100 <= Node.val <= 100 

二、解法1-层序遍历 O(N)

        这个题可以用层序遍历来完成,但是方向是从右向左进行,只将每层的第一个节点放入数组中。

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        vector<int> ret;
        queue<TreeNode*> q1;
        q1.push(root);
        while(!q1.empty())
        {
            queue<TreeNode*> q2;
            int oldLen = ret.size();
            while(!q1.empty())
            {
                root = q1.front();
                q1.pop();
                if(root != nullptr)
                {
                    q2.push(root->right);
                    q2.push(root->left);
                    if(ret.size() == oldLen)
                        ret.push_back(root->val);
                }
            }
            q1 = q2;
        }
        return ret;
    }
};

三、解法2-递归 O(N)

        从最右路径遍历,然后遍历次右路径,最后遍历最左路径,如果某条路径比它所有右边路径中的最长路径还要长,那么多出来的节点就是右视图能看见的,将其加入结果中。

class Solution {
public:
    void _rightSideView(TreeNode* root,int deep)
    {
        if(root == nullptr)
            return;
        if(deep > maxDeep) // 当前深度比左边路径的最长路径还要深
        {
            maxDeep = deep; // 更新最大深度
            ret.push_back(root->val); // 将当前节点加入结果
        }
        _rightSideView(root->right,deep+1); // 先遍历右路径
        _rightSideView(root->left,deep+1);  // 后遍历左路径
    }
    vector<int> rightSideView(TreeNode* root) {
        _rightSideView(root,1);
        return ret;
    }
private:
    int maxDeep = 0; // 最大深度
    vector<int> ret;
};

        递归的迭代版本:

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        stack<pair<TreeNode*, int>> s; // 存储节点和节点的当前深度
        s.push({root, 1});
        int maxDeep = 0; // 最大深度
        vector<int> ret;
        while (!s.empty()) {
            if (s.top().first) {
                root = s.top().first;
                int deep = s.top().second;
                s.pop();
                if (root != nullptr) {
                    if (deep > maxDeep) {
                        maxDeep = deep;
                        ret.push_back(root->val);
                    }
                    s.push({root->left, deep + 1});
                    s.push({root->right, deep + 1});
                }
            }
            else
                s.pop();
        }
        return ret;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值