Skip to content

Commit 6a2809c

Browse files
authored
Merge pull request #1775 from PradnyaGaitonde/PradnyaGaitonde-patch-19
Create 0589-N-ary-Tree-Preorder-Traversal.md
2 parents c7448a2 + 8e59800 commit 6a2809c

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
---
2+
id: n-ary-tree-preorder-traversal
3+
title: N-ary Tree Preorder Traversal(LeetCode)
4+
sidebar_label: 0589-N-ary Tree Preorder Traversal
5+
tags:
6+
- Stack
7+
- Tree
8+
- Depth-first search
9+
description: Given the root of an n-ary tree, return the preorder traversal of its nodes' values.
10+
---
11+
12+
## Problem Statement
13+
14+
Given the `root` of an n-ary tree, return the preorder traversal of its nodes' values.
15+
16+
Nary-Tree input serialization is represented in their level order traversal. Each group of children is separated by the null value (See examples)
17+
18+
### Examples
19+
20+
**Example 1:**
21+
22+
![image](https://github.com/PradnyaGaitonde/codeharborhub.github.io/assets/116059908/10ac19a3-6628-46b8-99fe-1da89fa67210)
23+
24+
```plaintext
25+
Input: root = [1,null,3,2,4,null,5,6]
26+
Output: [1,3,5,6,2,4]
27+
```
28+
29+
**Example 2:**
30+
31+
![image](https://github.com/PradnyaGaitonde/codeharborhub.github.io/assets/116059908/b40bd1b8-ad90-47fc-b034-7aa97b4ca6a6)
32+
33+
```plaintext
34+
Input: root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
35+
Output: [1,2,3,6,7,11,14,4,8,12,5,9,13,10]
36+
```
37+
38+
### Constraints
39+
40+
- The number of nodes in the tree is in the range `[0, 104]`.
41+
- `0 <= Node.val <= 104`
42+
- The height of the n-ary tree is less than or equal to `1000`.
43+
44+
## Solution
45+
46+
Preorder traversal is a common tree traversal method where the nodes are visited in the order: root, then the children from left to right. We will explore two approaches to perform preorder traversal on an N-ary tree: a recursive solution and an iterative solution.
47+
48+
### Approach 1: Recursive Solution
49+
50+
#### Algorithm
51+
52+
1. Define a recursive function `dfs` that takes a node and an output list as arguments.
53+
2. If the node is `None`, return immediately.
54+
3. Append the value of the node to the output list.
55+
4. Recursively call the `dfs` function on each child of the node.
56+
5. The main function `preorder` initializes the output list and calls the `dfs` function with the root node.
57+
58+
#### Implementation
59+
60+
```Python
61+
# Definition for a Node.
62+
class Node(object):
63+
def __init__(self, val=None, children=None):
64+
self.val = val
65+
self.children = children
66+
67+
class Solution(object):
68+
def preorder(self, root):
69+
"""
70+
:type root: Node
71+
:rtype: List[int]
72+
"""
73+
74+
output = []
75+
76+
# Perform DFS on the root and get the output stack
77+
self.dfs(root, output)
78+
79+
# Return the output of all the nodes.
80+
return output
81+
82+
def dfs(self, root, output):
83+
# If root is none, return
84+
if root is None:
85+
return
86+
87+
# For preorder, we first add the root value
88+
output.append(root.val)
89+
90+
# Then add all the children to the output
91+
for child in root.children:
92+
self.dfs(child, output)
93+
```
94+
95+
### Complexity Analysis
96+
97+
- **Time complexity**: $O(N)$ - where N is the number of nodes in the tree. Each node is visited exactly once.
98+
- **Space complexity**: $O(H)$ - where H is the height of the tree. This is due to the recursion stack.
99+
100+
### Approach 2: Iterative Solution
101+
102+
#### Algorithm
103+
104+
1. Initialize a stack with the root node.
105+
2. Initialize an empty output list.
106+
3. While the stack is not empty:
107+
* Pop the last element from the stack and append its value to the output list.
108+
* Extend the stack with the children of the popped node in reverse order.
109+
4. Return the output list.
110+
111+
#### Implementation
112+
113+
```Python
114+
# Definition for a Node.
115+
class Node(object):
116+
def __init__(self, val=None, children=None):
117+
self.val = val
118+
self.children = children
119+
120+
class Solution(object):
121+
def preorder(self, root):
122+
"""
123+
:type root: Node
124+
:rtype: List[int]
125+
"""
126+
if root is None:
127+
return []
128+
129+
stack = [root]
130+
output = []
131+
132+
# Till there is an element in the stack, the loop runs.
133+
while stack:
134+
# Pop the last element from the stack and store it into temp.
135+
temp = stack.pop()
136+
137+
# Append the value of temp to output
138+
output.append(temp.val)
139+
140+
# Add the children of the temp into the stack in reverse order.
141+
# Children of 1 = [3, 2, 4], if not reversed then 4 will be popped out first from the stack.
142+
# If reversed then stack = [4, 2, 3]. Here 3 will pop out first.
143+
# This continues till the stack is empty.
144+
stack.extend(temp.children[::-1])
145+
146+
# Return the output
147+
return output
148+
```
149+
150+
### Complexity Analysis
151+
152+
- **Time complexity**: $O(N)$
153+
- **Space complexity**: $O(N)
154+
155+
### Conclusion
156+
157+
Both the recursive and iterative solutions for preorder traversal of an N-ary tree have similar time complexities of O(N), making them efficient for large trees. The recursive solution has a space complexity of O(H), making it potentially less efficient for deep trees due to the recursion stack. The iterative solution has a space complexity of O(N), which can handle all nodes without the risk of a stack overflow. The choice between the two approaches depends on the specific constraints and requirements of the problem at hand.

0 commit comments

Comments
 (0)