|
| 1 | + |
| 2 | +<!-- problem:start --> |
| 3 | + |
| 4 | +# [199. Binary Tree Right Side View](https://leetcode.com/problems/binary-tree-right-side-view) |
| 5 | + |
| 6 | +- **comments**: true |
| 7 | +- **difficulty**: Medium |
| 8 | + |
| 9 | +- **tags**: |
| 10 | + - Tree |
| 11 | + - Depth-First Search |
| 12 | + - Breadth-First Search |
| 13 | + - Binary Tree |
| 14 | +--- |
| 15 | + |
| 16 | +## Description |
| 17 | + |
| 18 | +<!-- description:start --> |
| 19 | + |
| 20 | +<p>Given the <code>root</code> of a binary tree, imagine yourself standing on the <strong>right side</strong> of it, return <em>the values of the nodes you can see ordered from top to bottom</em>.</p> |
| 21 | + |
| 22 | +<p> </p> |
| 23 | +<p><strong class="example">Example 1:</strong></p> |
| 24 | + |
| 25 | +<div class="example-block"> |
| 26 | +<p><strong>Input:</strong> <span class="example-io">root = [1,2,3,null,5,null,4]</span></p> |
| 27 | + |
| 28 | +<p><strong>Output:</strong> <span class="example-io">[1,3,4]</span></p> |
| 29 | + |
| 30 | +<p><strong>Explanation:</strong></p> |
| 31 | + |
| 32 | +<p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/0100-0199/0199.Binary%20Tree%20Right%20Side%20View/images/tmpd5jn43fs-1.png" style="width: 400px; height: 207px;" /></p> |
| 33 | +</div> |
| 34 | + |
| 35 | +<p><strong class="example">Example 2:</strong></p> |
| 36 | + |
| 37 | +<div class="example-block"> |
| 38 | +<p><strong>Input:</strong> <span class="example-io">root = [1,2,3,4,null,null,null,5]</span></p> |
| 39 | + |
| 40 | +<p><strong>Output:</strong> <span class="example-io">[1,3,4,5]</span></p> |
| 41 | + |
| 42 | +<p><strong>Explanation:</strong></p> |
| 43 | + |
| 44 | +<p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/0100-0199/0199.Binary%20Tree%20Right%20Side%20View/images/tmpkpe40xeh-1.png" style="width: 400px; height: 214px;" /></p> |
| 45 | +</div> |
| 46 | + |
| 47 | +<p><strong class="example">Example 3:</strong></p> |
| 48 | + |
| 49 | +<div class="example-block"> |
| 50 | +<p><strong>Input:</strong> <span class="example-io">root = [1,null,3]</span></p> |
| 51 | + |
| 52 | +<p><strong>Output:</strong> <span class="example-io">[1,3]</span></p> |
| 53 | +</div> |
| 54 | + |
| 55 | +<p><strong class="example">Example 4:</strong></p> |
| 56 | + |
| 57 | +<div class="example-block"> |
| 58 | +<p><strong>Input:</strong> <span class="example-io">root = []</span></p> |
| 59 | + |
| 60 | +<p><strong>Output:</strong> <span class="example-io">[]</span></p> |
| 61 | +</div> |
| 62 | + |
| 63 | +<p> </p> |
| 64 | +<p><strong>Constraints:</strong></p> |
| 65 | + |
| 66 | +<ul> |
| 67 | + <li>The number of nodes in the tree is in the range <code>[0, 100]</code>.</li> |
| 68 | + <li><code>-100 <= Node.val <= 100</code></li> |
| 69 | +</ul> |
| 70 | + |
| 71 | +<!-- description:end --> |
| 72 | + |
| 73 | +## Solutions |
| 74 | + |
| 75 | +<!-- solution:start --> |
| 76 | + |
| 77 | +### Solution 1: BFS |
| 78 | + |
| 79 | +We can use breadth-first search (BFS) and define a queue $\textit{q}$ to store the nodes. We start by putting the root node into the queue. Each time, we take out all the nodes of the current level from the queue. For the current node, we first check if the right subtree exists; if it does, we put the right subtree into the queue. Then, we check if the left subtree exists; if it does, we put the left subtree into the queue. This way, the first node taken out from the queue each time is the rightmost node of that level. |
| 80 | + |
| 81 | +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree. |
| 82 | + |
| 83 | +<!-- tabs:start --> |
| 84 | + |
| 85 | +#### Python3 |
| 86 | + |
| 87 | +```python |
| 88 | +# Definition for a binary tree node. |
| 89 | +# class TreeNode: |
| 90 | +# def __init__(self, val=0, left=None, right=None): |
| 91 | +# self.val = val |
| 92 | +# self.left = left |
| 93 | +# self.right = right |
| 94 | +class Solution: |
| 95 | + def rightSideView(self, root: Optional[TreeNode]) -> List[int]: |
| 96 | + ans = [] |
| 97 | + if root is None: |
| 98 | + return ans |
| 99 | + q = deque([root]) |
| 100 | + while q: |
| 101 | + ans.append(q[0].val) |
| 102 | + for _ in range(len(q)): |
| 103 | + node = q.popleft() |
| 104 | + if node.right: |
| 105 | + q.append(node.right) |
| 106 | + if node.left: |
| 107 | + q.append(node.left) |
| 108 | + return ans |
| 109 | +``` |
| 110 | + |
| 111 | +#### Java |
| 112 | + |
| 113 | +```java |
| 114 | +/** |
| 115 | + * Definition for a binary tree node. |
| 116 | + * public class TreeNode { |
| 117 | + * int val; |
| 118 | + * TreeNode left; |
| 119 | + * TreeNode right; |
| 120 | + * TreeNode() {} |
| 121 | + * TreeNode(int val) { this.val = val; } |
| 122 | + * TreeNode(int val, TreeNode left, TreeNode right) { |
| 123 | + * this.val = val; |
| 124 | + * this.left = left; |
| 125 | + * this.right = right; |
| 126 | + * } |
| 127 | + * } |
| 128 | + */ |
| 129 | +class Solution { |
| 130 | + public List<Integer> rightSideView(TreeNode root) { |
| 131 | + List<Integer> ans = new ArrayList<>(); |
| 132 | + if (root == null) { |
| 133 | + return ans; |
| 134 | + } |
| 135 | + Deque<TreeNode> q = new ArrayDeque<>(); |
| 136 | + q.offer(root); |
| 137 | + while (!q.isEmpty()) { |
| 138 | + ans.add(q.peekFirst().val); |
| 139 | + for (int k = q.size(); k > 0; --k) { |
| 140 | + TreeNode node = q.poll(); |
| 141 | + if (node.right != null) { |
| 142 | + q.offer(node.right); |
| 143 | + } |
| 144 | + if (node.left != null) { |
| 145 | + q.offer(node.left); |
| 146 | + } |
| 147 | + } |
| 148 | + } |
| 149 | + return ans; |
| 150 | + } |
| 151 | +} |
| 152 | +``` |
| 153 | + |
| 154 | +#### C++ |
| 155 | + |
| 156 | +```cpp |
| 157 | +/** |
| 158 | + * Definition for a binary tree node. |
| 159 | + * struct TreeNode { |
| 160 | + * int val; |
| 161 | + * TreeNode *left; |
| 162 | + * TreeNode *right; |
| 163 | + * TreeNode() : val(0), left(nullptr), right(nullptr) {} |
| 164 | + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} |
| 165 | + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} |
| 166 | + * }; |
| 167 | + */ |
| 168 | +class Solution { |
| 169 | +public: |
| 170 | + vector<int> rightSideView(TreeNode* root) { |
| 171 | + vector<int> ans; |
| 172 | + if (!root) { |
| 173 | + return ans; |
| 174 | + } |
| 175 | + queue<TreeNode*> q{{root}}; |
| 176 | + while (q.size()) { |
| 177 | + ans.push_back(q.front()->val); |
| 178 | + for (int k = q.size(); k; --k) { |
| 179 | + auto node = q.front(); |
| 180 | + q.pop(); |
| 181 | + if (node->right) { |
| 182 | + q.push(node->right); |
| 183 | + } |
| 184 | + if (node->left) { |
| 185 | + q.push(node->left); |
| 186 | + } |
| 187 | + } |
| 188 | + } |
| 189 | + return ans; |
| 190 | + } |
| 191 | +}; |
| 192 | +``` |
| 193 | +
|
| 194 | +#### Go |
| 195 | +
|
| 196 | +```go |
| 197 | +/** |
| 198 | + * Definition for a binary tree node. |
| 199 | + * type TreeNode struct { |
| 200 | + * Val int |
| 201 | + * Left *TreeNode |
| 202 | + * Right *TreeNode |
| 203 | + * } |
| 204 | + */ |
| 205 | +func rightSideView(root *TreeNode) (ans []int) { |
| 206 | + if root == nil { |
| 207 | + return |
| 208 | + } |
| 209 | + q := []*TreeNode{root} |
| 210 | + for len(q) > 0 { |
| 211 | + ans = append(ans, q[0].Val) |
| 212 | + for k := len(q); k > 0; k-- { |
| 213 | + node := q[0] |
| 214 | + q = q[1:] |
| 215 | + if node.Right != nil { |
| 216 | + q = append(q, node.Right) |
| 217 | + } |
| 218 | + if node.Left != nil { |
| 219 | + q = append(q, node.Left) |
| 220 | + } |
| 221 | + } |
| 222 | + } |
| 223 | + return |
| 224 | +} |
| 225 | +``` |
| 226 | + |
| 227 | +#### TypeScript |
| 228 | + |
| 229 | +```ts |
| 230 | +/** |
| 231 | + * Definition for a binary tree node. |
| 232 | + * class TreeNode { |
| 233 | + * val: number |
| 234 | + * left: TreeNode | null |
| 235 | + * right: TreeNode | null |
| 236 | + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { |
| 237 | + * this.val = (val===undefined ? 0 : val) |
| 238 | + * this.left = (left===undefined ? null : left) |
| 239 | + * this.right = (right===undefined ? null : right) |
| 240 | + * } |
| 241 | + * } |
| 242 | + */ |
| 243 | + |
| 244 | +function rightSideView(root: TreeNode | null): number[] { |
| 245 | + const ans: number[] = []; |
| 246 | + if (!root) { |
| 247 | + return ans; |
| 248 | + } |
| 249 | + const q: TreeNode[] = [root]; |
| 250 | + while (q.length > 0) { |
| 251 | + ans.push(q[0].val); |
| 252 | + const nq: TreeNode[] = []; |
| 253 | + for (const { left, right } of q) { |
| 254 | + if (right) { |
| 255 | + nq.push(right); |
| 256 | + } |
| 257 | + if (left) { |
| 258 | + nq.push(left); |
| 259 | + } |
| 260 | + } |
| 261 | + q.length = 0; |
| 262 | + q.push(...nq); |
| 263 | + } |
| 264 | + return ans; |
| 265 | +} |
| 266 | +``` |
| 267 | + |
| 268 | +#### Rust |
| 269 | + |
| 270 | +```rust |
| 271 | +// Definition for a binary tree node. |
| 272 | +// #[derive(Debug, PartialEq, Eq)] |
| 273 | +// pub struct TreeNode { |
| 274 | +// pub val: i32, |
| 275 | +// pub left: Option<Rc<RefCell |
| 276 | + |
| 277 | +<TreeNode>>>, |
| 278 | +// pub right: Option<Rc<RefCell<TreeNode>>>, |
| 279 | +// } |
| 280 | +// impl TreeNode { |
| 281 | +// #[inline] |
| 282 | +// pub fn new(val: i32) -> Self { |
| 283 | +// TreeNode { |
| 284 | +// val, |
| 285 | +// left: None, |
| 286 | +// right: None, |
| 287 | +// } |
| 288 | +// } |
| 289 | +// } |
| 290 | + |
| 291 | +use std::collections::VecDeque; |
| 292 | + |
| 293 | +impl Solution { |
| 294 | + pub fn right_side_view(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> { |
| 295 | + let mut ans = Vec::new(); |
| 296 | + if root.is_none() { |
| 297 | + return ans; |
| 298 | + } |
| 299 | + let mut queue = VecDeque::new(); |
| 300 | + queue.push_back(root); |
| 301 | + while !queue.is_empty() { |
| 302 | + let len = queue.len(); |
| 303 | + ans.push(queue.front().unwrap().borrow().val); |
| 304 | + for _ in 0..len { |
| 305 | + let node = queue.pop_front().unwrap(); |
| 306 | + if node.borrow().right.is_some() { |
| 307 | + queue.push_back(node.borrow().right.clone()); |
| 308 | + } |
| 309 | + if node.borrow().left.is_some() { |
| 310 | + queue.push_back(node.borrow().left.clone()); |
| 311 | + } |
| 312 | + } |
| 313 | + } |
| 314 | + ans |
| 315 | + } |
| 316 | +} |
| 317 | +``` |
| 318 | + |
| 319 | +<!-- tabs:end --> |
| 320 | + |
| 321 | +## Explanation |
| 322 | + |
| 323 | +To solve this problem, we can use a breadth-first search (BFS) approach. The idea is to traverse the tree level by level and collect the first node that is visible from the right side at each level. This can be achieved by using a queue to store the nodes of the tree and processing each level one by one. At each level, we add the first node to our result list since it represents the rightmost node at that level. This ensures that the nodes we collect are in the correct order. |
| 324 | + |
| 325 | +### Complexity Analysis |
| 326 | +- **Time Complexity**: O(n), where n is the number of nodes in the tree. Each node is visited exactly once during the BFS traversal. |
| 327 | +- **Space Complexity**: O(n), where n is the maximum number of nodes at any level in the tree, which can be at most the number of leaf nodes in the tree. |
| 328 | + |
| 329 | +<!-- solution:end --> |
| 330 | + |
| 331 | +<!-- problem:end --> |
0 commit comments