-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path606-ConstructStringFromBinaryTree.go
More file actions
167 lines (153 loc) · 6.03 KB
/
606-ConstructStringFromBinaryTree.go
File metadata and controls
167 lines (153 loc) · 6.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package main
// 606. Construct String from Binary Tree
// Given the root node of a binary tree,
// your task is to create a string representation of the tree following a specific set of formatting rules.
// The representation should be based on a preorder traversal of the binary tree and must adhere to the following guidelines:
// 1. Node Representation: Each node in the tree should be represented by its integer value.
// 2. Parentheses for Children: If a node has at least one child (either left or right),
// its children should be represented inside parentheses. Specifically:
// 2.1 If a node has a left child, the value of the left child should be enclosed in parentheses immediately following the node's value.
// 2.2 If a node has a right child, the value of the right child should also be enclosed in parentheses.
// The parentheses for the right child should follow those of the left child.
// 3. Omitting Empty Parentheses: Any empty parentheses pairs (i.e., ()) should be omitted from the final string representation of the tree, with one specific exception: when a node has a right child but no left child.
// In such cases, you must include an empty pair of parentheses to indicate the absence of the left child.
// This ensures that the one-to-one mapping between the string representation and the original binary tree structure is maintained.
// In summary, empty parentheses pairs should be omitted when a node has only a left child or no children.
// However, when a node has a right child but no left child, an empty pair of parentheses must precede the representation of the right child to reflect the tree's structure accurately.
// Example 1:
// 1
// / \
// 2 3
// /
// 4
// <img src="https://assets.leetcode.com/uploads/2021/05/03/cons1-tree.jpg" />
// Input: root = [1,2,3,4]
// Output: "1(2(4))(3)"
// Explanation: Originally, it needs to be "1(2(4)())(3()())", but you need to omit all the empty parenthesis pairs. And it will be "1(2(4))(3)".
// Example 2:
// 1
// / \
// 2 3
// \
// 4
// <img src="https://assets.leetcode.com/uploads/2021/05/03/cons2-tree.jpg" />
// Input: root = [1,2,3,null,4]
// Output: "1(2()(4))(3)"
// Explanation: Almost the same as the first example, except the () after 2 is necessary to indicate the absence of a left child for 2 and the presence of a right child.
// Constraints:
// The number of nodes in the tree is in the range [1, 10^4].
// -1000 <= Node.val <= 1000
import "fmt"
import "strconv"
import "strings"
// Definition for a binary tree node.
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
// Recursion
func tree2str(t *TreeNode) string {
var dfs func (node *TreeNode) string
dfs = func (node *TreeNode) string {
if node == nil {
return ""
}
if node.Left != nil && node.Right != nil {
return fmt.Sprintf("%d(%s)(%s)", node.Val, dfs(node.Left), dfs(node.Right))
} else if node.Left == nil && node.Right == nil {
return strconv.Itoa(node.Val)
} else if node.Left != nil {
return fmt.Sprintf("%d(%s)", node.Val, dfs(node.Left))
} else {
return fmt.Sprintf("%d()(%s)", node.Val, dfs(node.Right))
}
}
return dfs(t)
}
func tree2str1(root *TreeNode) string {
var dfs func(root *TreeNode) string
dfs = func(root *TreeNode) string {
switch {
case root == nil:
return ""
case root.Left == nil && root.Right == nil:
return strconv.Itoa(root.Val)
case root.Right == nil:
return fmt.Sprintf("%d(%s)", root.Val, dfs(root.Left))
default:
return fmt.Sprintf("%d(%s)(%s)", root.Val, dfs(root.Left), dfs(root.Right))
}
}
return dfs(root)
}
func tree2str2(root *TreeNode) string {
var dfs func(root *TreeNode) string
dfs = func(root *TreeNode) string {
r := &strings.Builder{}
r.WriteString(strconv.Itoa(root.Val))
if root.Left == nil && root.Right == nil {
return r.String()
}
if root.Left != nil{
r.WriteByte('(')
r.WriteString(dfs(root.Left))
r.WriteByte(')')
} else {
r.WriteString("()")
}
if root.Right != nil{
r.WriteByte('(')
r.WriteString(dfs(root.Right))
r.WriteByte(')')
}
return r.String()
}
return dfs(root)
}
func main() {
// Example 1:
// 1
// / \
// 2 3
// /
// 4
// <img src="https://assets.leetcode.com/uploads/2021/05/03/cons1-tree.jpg" />
// Input: root = [1,2,3,4]
// Output: "1(2(4))(3)"
// Explanation: Originally, it needs to be "1(2(4)())(3()())", but you need to omit all the empty parenthesis pairs. And it will be "1(2(4))(3)".
tree1 := &TreeNode{
1,
&TreeNode{2, &TreeNode{5, nil, nil}, nil, },
&TreeNode{3, nil, nil, },
}
fmt.Println(tree2str(tree1)) // "1(2(4))(3)"
// Example 2:
// 1
// / \
// 2 3
// \
// 4
// <img src="https://assets.leetcode.com/uploads/2021/05/03/cons2-tree.jpg" />
// Input: root = [1,2,3,null,4]
// Output: "1(2()(4))(3)"
// Explanation: Almost the same as the first example, except the () after 2 is necessary to indicate the absence of a left child for 2 and the presence of a right child.
tree2 := &TreeNode{
1,
&TreeNode{2, nil, &TreeNode{5, nil, nil}, },
&TreeNode{3, nil, nil, },
}
fmt.Println(tree2str(tree2)) // "1(2()(4))(3)"
fmt.Println(tree2str1(tree1)) // "1(2(4))(3)"
fmt.Println(tree2str1(tree2)) // "1(2()(4))(3)"
fmt.Println(tree2str2(tree1)) // "1(2(4))(3)"
fmt.Println(tree2str2(tree2)) // "1(2()(4))(3)"
}