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]
defhasNext(self): while self.queue: if self.queue[0].isInteger(): returnTrue first = self.queue.popleft() self.queue.extendleft(first.getList()[::-1]) returnFalse
/** * // 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; * }; */ classNestedIterator { 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]); } }
intnext(){ NestedInteger t = s.top(); s.pop(); return t.getInteger(); }
boolhasNext(){ while (!s.empty()) { NestedInteger t = s.top(); if (t.isInteger()) returntrue; //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]); } } returnfalse; }
private: stack<NestedInteger> s; };
/** * Your NestedIterator object will be instantiated and called as such: * NestedIterator i(nestedList); * while (i.hasNext()) cout << i.next(); */