Start learning free

LESSON 440 OF 568 · BINARY TREES

Binary Tree Right Side View in C++: Level-Order BFS with a Queue

Practice O(n) Read the full explanation

Given the root of a binary tree, imagine yourself standing on its right side. Return the values of the nodes you can see, ordered from top to bottom.

From the right you see exactly one node on each level: the rightmost node of that level, the last one when you read the level from left to right. It can belong to the left subtree, when the right subtree doesn't reach that deep. An empty tree shows nothing.

The trees below are written in level order (top to bottom, left to right), with NULL for a missing child.

 

Example 1:

    1
   / \
  2   3
   \   \
    5   4

Input: root = [1,2,3,NULL,5,NULL,4]
Output: [1,3,4]
Explanation: The first level is just 1. On the second level, 3 hides 2. On the third level, 4 hides 5.

Example 2:

      1
     / \
    2   3
   /
  4

Input: root = [1,2,3,4]
Output: [1,3,4]
Explanation: The third level has only 4. It is in the left subtree, but nothing stands to its right, so you see it.

Example 3:

Input: root = []
Output: []
Explanation: An empty tree has no levels, so you see no nodes.

 

Constraints:

  • The number of nodes in the tree is in the range [0, 100].
  • -100 <= Node.val <= 100
  • Values may repeat.

Note:

The tutorial walks the tree level by level with a queue. The queue starts with the root. At the start of each round it holds exactly one level: count its nodes, take them out one by one from the front, and put each node's children (left, then right) at the back, where they wait for the next round. The last node taken out in a round is the rightmost node of its level: that is the one you see.

Each node enters and leaves the queue once, so the time is O(n) for a tree of n nodes. The queue holds at most about two levels at a time, which is O(n) extra space in the worst case.

STEP 1 OF 11
    Ctrl + Enter to check

    C++ · BINARY TREES

    Binary Tree Right Side View in C++, explained

    Problem overview

    The method rightSideView receives the root of a binary tree and returns a vector<int>: the values you would see standing on the tree's right side, from the top level to the bottom one. From there you see exactly one node per level, the rightmost one. An empty tree gives an empty vector.

    The lesson provides the TreeNode struct, which has an int val and two pointers, left and right, that are null when the child is missing.

    In the first example the tree is [1,2,3,NULL,5,NULL,4]. Level 0 is just 1, level 1 is 2 and 3, and level 2 is 5 and 4. The rightmost nodes are 1, 3 and 4, so the answer is [1,3,4]. In the second example, [1,2,3,4], the node 4 is the only one on level 2. It hangs from the left child 2, yet nothing stands to its right, so it is visible and the answer is again [1,3,4].

    Approach: walk the tree one level at a time

    The tempting shortcut is to follow right pointers from the root. It fails as soon as the right subtree is shallower than the left one: for [1,2,3,4] it returns [1,3] and misses the 4. The question is about levels, not about right children, so the algorithm should group nodes by level.

    A queue does that. Start with the root in the queue. At the beginning of each round the queue holds exactly one level. Count its nodes, take that many out from the front, and push each one's children, left first, at the back. Those children wait there for the next round. Within a round the nodes leave from left to right, so the last node taken out is the rightmost of its level, and that is the value to record.

    On the first example the rounds look like this (the queue contents were printed from a run):

    RoundQueue size at the startNodes taken outRecorded
    1111
    222, 33
    325, 44

    Step by step

    1. Create the result. An empty vector<int> named result collects one value per level.
    2. Return early for an empty tree. The queue needs a first node, and a null root has none. Returning the empty result is the correct answer.
    3. Create the queue and push the root. A queue<TreeNode*> hands nodes back in the order they came in, which is what makes the visit go level by level.
    4. Loop while the queue isn't empty. Each pass of this loop handles one whole level.
    5. Store the level's size. int levelSize = q.size() is read once, before any child is pushed.
    6. Loop over exactly that many nodes. The children pushed during this loop belong to the next level, and counting up to levelSize keeps the loop from touching them.
    7. Take the next node with front(), then remove it with pop(). pop() returns nothing, so the read has to come first.
    8. Record the last node of the level. When i == levelSize - 1, push node->val into result.
    9. Push the left child if it exists.
    10. Push the right child if it exists. Left before right keeps every level in left-to-right order.
    11. Return result once the queue is empty.

    The solution in C++

    class Solution {
    public:
        vector<int> rightSideView(TreeNode* root) {
            vector<int> result;
            if (!root) {
                return result;
            }
            queue<TreeNode*> q;
            q.push(root);
            while (!q.empty()) {
                int levelSize = q.size();
                for (int i = 0; i < levelSize; i++) {
                    TreeNode* node = q.front();
                    q.pop();
                    if (i == levelSize - 1) {
                        result.push_back(node->val);
                    }
                    if (node->left) {
                        q.push(node->left);
                    }
                    if (node->right) {
                        q.push(node->right);
                    }
                }
            }
            return result;
        }
    };
    

    The C++ details worth a closer look:

    • The queue stores pointers. A queue<TreeNode*> holds addresses of nodes, not copies, so pushing a child is cheap and the nodes stay where they are in the tree.
    • q.size() is unsigned. It returns a size_t. Storing it in an int is fine here because a tree has at most 100 nodes, and it makes the comparison i < levelSize compare two signed values.
    • Null pointers are false. if (!root) and if (node->left) test a pointer directly: a null pointer counts as false and any other pointer as true.
    • front() and pop() are separate. front() returns a reference to the first element and does not remove it. pop() removes it and returns nothing. Calling front() on an empty queue is undefined behaviour, which the loop condition prevents.

    Complexity

    Time: O(n) for n nodes. Every node is pushed once and popped once, and each does a constant amount of work.

    Space: O(n). The queue holds at most two neighbouring levels at a time, and a level can contain about half of all the nodes, as in a complete tree. The result adds one value per level, which is smaller still.

    Edge cases and common mistakes

    • Empty tree. Without the !root check, q.push(root) would put a null pointer in the queue and node->val would dereference it. With the check, the empty tree returns [].
    • Following only right children. For [1,2,3,4] that gives [1,3], while the correct answer is [1,3,4].
    • Recording the first node of a level. Testing i == 0 instead of i == levelSize - 1 produces the left side view: [1,2,5] for the first example instead of [1,3,4].
    • A single node. The tree [7] has one level with one node, which is also its last, so the answer is [7].
    • A tree that is a left-leaning chain. The tree [1,2,NULL,3,NULL,4] has one node per level, so every node is visible and the answer is [1,2,3,4].
    • Duplicate values. Values may repeat, and that doesn't matter: the algorithm works with nodes and positions, never with values.

    Testing

    • [1,2,3,NULL,5,NULL,4] gives [1,3,4].
    • [1,2,3,4] gives [1,3,4].
    • [] gives [].
    • [7] gives [7].
    • [1,2,NULL,3,NULL,4] gives [1,2,3,4].
    • [1,2,3,4,5,6,7] (a full tree) gives [1,3,7].
    Keep going with C++500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free