-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathflatten-nested-list-iterator.go
142 lines (115 loc) · 3.16 KB
/
flatten-nested-list-iterator.go
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
package main
// source: https://leetcode.com/problems/flatten-nested-list-iterator/
// NestedInteger This is the interface that allows for creating nested lists.
// You should not implement it, or speculate about its implementation
type NestedInteger struct {
isInt bool
val int
nestedList []NestedInteger
}
// IsInteger Return true if this NestedInteger holds a single integer, rather than a nested root.
func (this NestedInteger) IsInteger() bool {
return this.isInt
}
// GetInteger Return the single integer that this NestedInteger holds, if it holds a single integer
// The result is undefined if this NestedInteger holds a nested root
// So before calling this method, you should have a check
func (this NestedInteger) GetInteger() int {
if this.isInt {
return this.val
}
return -1
}
// SetInteger Set this NestedInteger to hold a single integer.
func (n NestedInteger) SetInteger(value int) {
n.val = value
}
// Add Set this NestedInteger to hold a nested root and adds a nested integer to it.
func (this NestedInteger) Add(elem NestedInteger) {
}
// GetList Return the nested root that this NestedInteger holds, if it holds a nested root
// The root length is zero if this NestedInteger holds a single integer
// You can access NestedInteger's List element directly if you want to modify it
func (this NestedInteger) GetList() []*NestedInteger {
return []*NestedInteger{}
}
// Actual solution is below
/*
type Stack struct {
values []*NestedInteger
}
func NewStack() *Stack {
return &Stack{}
}
func (s *Stack) Push(val *NestedInteger) {
s.values = append(s.values, val)
}
func (s *Stack) Pop() (val *NestedInteger, ok bool) {
if len(s.values) == 0 {
return val, false
}
val = s.values[len(s.values)-1]
s.values = s.values[:len(s.values)-1]
return val, true
}
func (s *Stack) Len() int {
return len(s.values)
}
func (s *Stack) Top() *NestedInteger {
return s.values[len(s.values)-1]
}
type NestedIterator struct {
stack *Stack
root []*NestedInteger
}
func Constructor(nestedList []*NestedInteger) *NestedIterator {
res := new(NestedIterator)
res.root = nestedList
res.stack = NewStack()
res.stack.Push(nestedList[0])
return res
}
func (it *NestedIterator) Next() int {
var res int
cur := it.stack.Pop()
if cur.IsInteger() {
res = cur.GetInteger()
root := it.stack.Top()
}
}
func (it *NestedIterator) HasNext() bool {
}
*/
// This solution requires O(n) memory and uses DFS when building iterator. Alternative way
// is to use stack to track current position relative to the root NestedInteger
type NestedIterator struct {
values []int
cur int
}
func Constructor(nestedList []*NestedInteger) *NestedIterator {
it := new(NestedIterator)
var insert func(it *NestedIterator, val *NestedInteger)
insert = func(it *NestedIterator, val *NestedInteger) {
if val.IsInteger() {
it.values = append(it.values, val.GetInteger())
return
}
for _, i := range val.GetList() {
insert(it, i)
}
}
for _, i := range nestedList {
insert(it, i)
}
it.cur = -1
return it
}
func (it *NestedIterator) Next() int {
return it.values[it.cur]
}
func (it *NestedIterator) HasNext() bool {
if it.cur+1 < len(it.values) {
return true
}
return false
}