341 Flatten Nested List Iterator
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.
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]
.
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
Come up with solution on my own!
/**
* // 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:
stack<pair<vector<NestedInteger>, int>> s;
void findNext(stack<pair<vector<NestedInteger>, int>>& s) {
s.top().second += 1;
vector<NestedInteger> list;
int i;
while ( true ) {
list = s.top().first;
i = s.top().second;
if ( i == int(list.size()) ) {
while ( i == int(list.size()) ) {
s.pop();
if ( s.empty() ) return;
s.top().second += 1;
list = s.top().first;
i = s.top().second;
}
}
if ( list[i].isInteger() ) return;
s.push(pair<vector<NestedInteger>, int>(list[i].getList(), 0));
}
return;
}
NestedIterator(vector<NestedInteger> &nestedList) {
s.push(pair<vector<NestedInteger>, int>(nestedList, -1));
findNext(s);
return;
}
int next() {
auto list = s.top().first;
int i = s.top().second;
findNext(s);
return list[i].getInteger();
}
bool hasNext() {
return ( ! s.empty() );
}
};
/**
* Your NestedIterator object will be instantiated and called as such:
* NestedIterator i(nestedList);
* while (i.hasNext()) cout << i.next();
*/
my python test code...
def isNumber(n):
try:
len(n)
except:
return True
return False
def addNext(s):
s[-1][1] += 1
while ( True ):
nums, i = s[-1][0], s[-1][1]
if ( i == len(nums) ):
while ( i == len(nums) ):
s.pop(-1)
if ( len(s) == 0 ): return
s[-1][1] += 1
nums, i = s[-1][0], s[-1][1]
if ( isNumber(nums[i]) ): return
s.append([nums[i], 0])
def next(s):
print s
nums, i = s[-1][0], s[-1][1]
res = nums[i]
addNext(s)
return res
def hasNext(s):
return ( len(s) != 0 )
def it_print(nums):
s = []
s.append([nums, -1])
addNext(s)
while ( hasNext(s) ):
print next(s)
nums = [[1,1], 2, [1, 1]]
print nums
it_print(nums)
Take [[1, 1], 2, [1, 1]]
as an example, the stack and the next element is like follows:
[[[[1, 1], 2, [1, 1]], 0], [[1, 1], 0]]
1
[[[[1, 1], 2, [1, 1]], 0], [[1, 1], 1]]
1
[[[[1, 1], 2, [1, 1]], 1]]
2
[[[[1, 1], 2, [1, 1]], 2], [[1, 1], 0]]
1
[[[[1, 1], 2, [1, 1]], 2], [[1, 1], 1]]
1