Binary Tree Right Side View

Updated on 13 May, 2025
Binary Tree Right Side View header image

Problem Statement

In this problem, we are given the root of a binary tree. The task is to view the tree from its right side and return the values of the nodes that are visible, from the top to the bottom. The "right side view" essentially means the nodes you would see if you were standing on the right side of the tree and looking towards it. This problem captures not only the depth but also the hierarchy of visible nodes when seen from a specified direction.

Examples

Example 1

Input:

root = [1,2,3,null,5,null,4]

Output:

[1,3,4]

Explanation:

Example 2

Input:

root = [1,2,3,4,null,null,null,5]

Output:

[1,3,4,5]

Explanation:

Example 3

Input:

root = [1,null,3]

Output:

[1,3]

Example 4

Input:

root = []

Output:

[]

Constraints

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

Approach and Intuition

The examples provide clear scenarios of viewing a binary tree from its right side. To form an intuitive understanding of the problem:

  1. Traverse Depth-first Rightwards: To ensure that we capture the rightmost node of each level first, a depth-first search (DFS) seems a good approach. By traversing the right subtree before the left subtree, we can prioritize right-visible nodes.

  2. Level-specific Handling: We can apply a level-counter to keep track of depths and ensure the first node visited at each new depth is included in the result, as this would be the rightmost node at that depth seen for the first time.

  3. Iterative Method: We could use a queue to store nodes along with their corresponding depths. Process each node by checking if it is the first node you are accessing at that particular depth—this node would represent the visible node for that depth from the right side.

  4. Special Cases:

    • An empty tree should return an empty list.
    • Trees with a very linear structure, like having nodes only on the right or only on the left, should still correctly identify the visible nodes.

From these examples, we can derive the rules and expected results:

  • For Example 1 with input root = [1,2,3,null,5,null,4], the output is [1,3,4]. Here, at each level of depth, you are seeing the rightmost nodes.
  • For Example 2 where the input is root = [1,2,3,4,null,null,null,5], the method returns [1,3,4,5], reflecting a tree where we drill down deeper into the right, combining depths where necessary.
  • Example 3 root = [1,null,3] simplifies to [1,3] showcasing a tree with nodes directly visible in a straightforward linear right path.
  • For an empty tree in Example 4, as expected, root = [] produces an empty output [].

By applying these steps and observations across differing structures of binary trees, one can efficiently compile the list of right side views irrespective of node positioning beyond the aforementioned constraints.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    vector<int> rightView;

    void traverse(TreeNode* node, int depth) {
        if (depth == rightView.size()) rightView.push_back(node->val);

        if (node->right != nullptr) traverse(node->right, depth + 1);
        if (node->left != nullptr) traverse(node->left, depth + 1);
    }

    vector<int> rightSideView(TreeNode* root) {
        if (root == nullptr) return rightView;

        traverse(root, 0);
        return rightView;
    }
};

This C++ code provides a solution to generating the right side view of a binary tree. The outlined approach uses depth-first search (DFS) to traverse the tree, giving priority to the rightmost nodes. The function rightSideView initializes the traversal, managing the scenario when the root is null by returning an empty vector.

The recursive function traverse is called initially from rightSideView. Here's how it operates:

  • It accepts two parameters: node (the current tree node) and depth (the depth level of the current node).
  • A check ensures new tree levels have their rightmost element added to the rightView vector.
  • The right child of the current node is processed first to ensure the rightmost nodes are considered before left child nodes at the same depth level.

Key features of the code include:

  • Priority traversal of right children before left children.
  • Efficient tracking and updating of maximum depth levels to ensure only the rightmost element at each depth level is captured.
  • A check to exit the traversal if the passed tree node is null, ensuring that no operations are performed on an empty subtree.

The result, stored in rightView, is a vector of integers that captures the values seen when viewing the tree from the right side. This vector is returned when the traversal completes. The solution efficiently records the desirable view by leveraging recursion and conditional checks based on tree depth and node existence.

java
class Solution {
    List<Integer> rightViewList = new ArrayList();

    public void traverseRight(TreeNode curNode, int depth) {
        if (depth == rightViewList.size()) rightViewList.add(curNode.val);

        if (curNode.right != null) traverseRight(curNode.right, depth + 1);
        if (curNode.left != null) traverseRight(curNode.left, depth + 1);
    }

    public List<Integer> rightSideView(TreeNode rootNode) {
        if (rootNode == null) return rightViewList;

        traverseRight(rootNode, 0);
        return rightViewList;
    }
}

This Java solution implements a method to generate the right side view of a binary tree. The approach primarily involves performing a depth-first traversal (DFS) while prioritizing the right subtree to ensure that the rightmost elements at each depth level are captured first.

  • The traverseRight method accepts a TreeNode representing the current node and an integer depth which indicates the current depth of the node in the tree.
  • A check is performed to see if the size of rightViewList equals the current depth. If true, it suggests that this is the first node encountered at this depth, and its value is added to rightViewList.
  • Recursion is used to traverse the right subtree first and then the left subtree, hence ensuring that the rightmost nodes are processed first.
  • The main method rightSideView initializes the rightViewList and calls traverseRight starting from the root. If the root is null, it returns the empty list.
  • Finally, after traversal, the accumulated list rightViewList is returned, representing the node values visible when looking at the tree from the right side.

This technique leverages the nature of DFS and the characteristics of a list's size compared to tree depth to ensure that only the rightmost elements from each level of the tree populate the resultant list. This ensures a space-optimized solution as additional data structures to track visited nodes or nodes per level are not required.

python
class Solution:
    def viewFromRight(self, rootNode: TreeNode) -> List[int]:
        if not rootNode:
            return []

        result = []

        def traverseRight(node: TreeNode, depth: int) -> None:
            if depth == len(result):
                result.append(node.val)
            for nextNode in [node.right, node.left]:
                if nextNode:
                    traverseRight(nextNode, depth + 1)

        traverseRight(rootNode, 0)
        return result

The given Python code defines a method to compute the right side view of a binary tree. When invoked, the method viewFromRight returns a list of integer values representing the nodes visible when looking at the tree from the right side.

  • The method initiates by checking if the rootNode is None. If true, an empty list is returned.
  • It initializes an empty list result to store the visible nodes.
  • A nested function traverseRight is defined to perform a depth-first search of the tree. It receives a node and its depth as arguments.
  • Inside traverseRight, if the current depth equals the length of result, it appends the node's value to result. This ensures only the rightmost node at each depth level is added.
  • The function iterates through the node's right and left children, invoking traverseRight recursively with an increased depth.
  • After defining the nested function, traverseRight is called with the rootNode and initial depth 0.
  • The list result, which now contains the nodes' values visible from the right, is returned.

Follow these guidelines to understand and utilize this function effectively in your Python projects involving binary tree manipulations.

Comments

No comments yet.