Problem description:

Given a nested list of integers, implement an iterator to flatten it.

Each element is either an integer, or a list – whose elements may also be integers or other lists.

1
2
3
4
Example 1:
Given the list [[1,1],2,[1,1]],

By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,1,2,1,1].

1
2
3
4
Example 2:
Given the list [1,[4,[6]]],

By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,4,6].

Solution:

first, we can store all the elements in reverse order with a stack. The reason that we need to use reverse order is because Stack is Last in First out. We can use the following example to explain.

1
2
3
4
5
6
7
8
9
index:  0 1 2 3 4 5
data: a b e d c q

___________
stack a b e d c q|
-----------
| |
last push |
first push

1
2
3
4
ex: queue [10, 20], list [0, -10, -20]
queue.extendleft(list) -> [-20, -10, 0, 10, 20]
but we want list to be original order
queue.extendlist(list[::-1]) -> [0, -10, -20, 10, 20]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class NestedIterator:

def __init__(self, nestedList):
self.queue = collections.deque(nestedList)

def next(self):
return self.queue.popleft().getInteger()

def hasNext(self):
while self.queue:
if self.queue[0].isInteger():
return True
first = self.queue.popleft()
self.queue.extendleft(first.getList()[::-1])
return False
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
/**
* // This is the interface that allows for creating nested lists.
* // You should not implement it, or speculate about its implementation
* class NestedInteger {
* public:
* // Return true if this NestedInteger holds a single integer, rather than a nested list.
* bool isInteger() const;
*
* // Return the single integer that this NestedInteger holds, if it holds a single integer
* // The result is undefined if this NestedInteger holds a nested list
* int getInteger() const;
*
* // Return the nested list that this NestedInteger holds, if it holds a nested list
* // The result is undefined if this NestedInteger holds a single integer
* const vector<NestedInteger> &getList() const;
* };
*/
class NestedIterator {
public:
NestedIterator(vector<NestedInteger> &nestedList) {
//because the stack is LIFO, so if we want to do A item in stack first, then we need to push item A in the last
for (int i = nestedList.size() - 1; i >= 0; --i) {
s.push(nestedList[i]);
}
}

int next() {
NestedInteger t = s.top();
s.pop();
return t.getInteger();
}

bool hasNext() {
while (!s.empty()) {
NestedInteger t = s.top();
if (t.isInteger()) return true; //if this element is a number, return true and let next() do the job
s.pop(); //this element is a list
for (int i = t.getList().size() - 1; i >= 0; --i) {
s.push(t.getList()[i]);
}
}
return false;
}

private:
stack<NestedInteger> s;
};

/**
* Your NestedIterator object will be instantiated and called as such:
* NestedIterator i(nestedList);
* while (i.hasNext()) cout << i.next();
*/

reference:
https://goo.gl/Ut4Pns