-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
124 lines (104 loc) · 2.36 KB
/
Copy pathmain.go
File metadata and controls
124 lines (104 loc) · 2.36 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
package main
import (
"fmt"
"strings"
"math"
)
/**
Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?
*/
// Definition for a binary tree node.
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
// first: implement the O(n) straight forward method
// 42ms, 76.92%
func recoverTree(root *TreeNode) {
var nodes []*TreeNode
var walk func(*TreeNode)
walk = func(n *TreeNode) {
if n == nil {
return
}
walk(n.Left)
nodes = append(nodes, n)
walk(n.Right)
}
walk(root)
// find two mistaken node with two pointer
var m, n int
for i := 0; i < len(nodes)-1; i++ {
if nodes[i].Val > nodes[i+1].Val {
m = i
break
}
}
for j := len(nodes) - 1; j > 0; j-- {
if nodes[j].Val < nodes[j-1].Val {
n = j
break
}
}
// swap m,n node's Val
nodes[m].Val, nodes[n].Val = nodes[n].Val, nodes[m].Val
}
// ref
var firstElement *TreeNode = nil
var secondElement *TreeNode = nil
var preElementVal *TreeNode = &TreeNode{Val: math.MinInt32}
func recoverTree2(root *TreeNode) {
if nil == root {
return
}
firstElement = nil
secondElement = nil
preElementVal = &TreeNode{Val: math.MinInt32}
TraceTree(root)
fmt.Println(firstElement.Val, secondElement.Val)
firstElement.Val, secondElement.Val = secondElement.Val, firstElement.Val
}
func TraceTree(root *TreeNode) {
if nil == root {
return
}
TraceTree(root.Left)
if nil == firstElement && preElementVal.Val >= root.Val {
firstElement = preElementVal
}
if nil != firstElement && preElementVal.Val >= root.Val {
secondElement = root
}
preElementVal = root
TraceTree(root.Right)
}
func (root *TreeNode) String() string {
var nodes []string
var walk func(*TreeNode)
walk = func(n *TreeNode) {
if n == nil {
return
}
walk(n.Left)
nodes = append(nodes, fmt.Sprintf("%d", n.Val))
walk(n.Right)
}
nodes = append(nodes, "[")
walk(root)
nodes = append(nodes, "]")
return strings.Join(nodes, " ")
}
func main() {
tree1 := &TreeNode{2, &TreeNode{3, nil, nil}, &TreeNode{1, nil, nil}}
recoverTree2(tree1)
fmt.Println(tree1)
tree4 := &TreeNode{10, &TreeNode{5, nil, nil}, &TreeNode{15, &TreeNode{6, nil, nil},
&TreeNode{20, nil, nil}}}
fmt.Println(tree4)
recoverTree(tree4)
fmt.Println(tree4)
}