Besides the common stack-based solutions, here is another recursive NestedIterator solution :)
class NestedIterator { int currInx; const vector<NestedInteger> &rData; NestedIterator *sub; void move() { if (currInx < 0 || rData[currInx].isInteger() || !sub->hasNext()) { if ((++currInx) < rData.size()) { releaseSub(); if (!rData[currInx].isInteger()) { // get next non-empty list while (currInx < rData.size() && ( sub = new NestedIterator(const_cast<vector<NestedInteger>&>(rData[currInx].getList())), (!rData[currInx].isInteger() && sub && !sub->hasNext())) ) { currInx++; releaseSub(); } } } } else { sub->move(); } } // NestedIterator() :rData(vector<NestedInteger>()), currInx(-1), sub(nullptr) { } void releaseSub() { delete sub; sub = nullptr; } public: ~NestedIterator() { releaseSub(); } NestedIterator(vector<NestedInteger> &nestedList) :rData(nestedList), currInx(-1), sub(nullptr) { move(); } int next() { int val = 0; if (rData[currInx].isInteger()) { val = rData[currInx].getInteger(); move(); } else { val = sub->next(); if (!sub->hasNext()) move(); } return val; } bool hasNext() { return currInx < rData.size() && (rData[currInx].isInteger() || sub->hasNext()); } };
And here's my stack-based solution:
class NestedIterator { vector<NestedInteger>& data; unsigned inx; stack<pair<NestedInteger*, unsigned>> stk; public: NestedIterator(vector<NestedInteger> &nestedList) :data(nestedList), inx(0) { if(data.size()) stk.push({ const_cast<NestedInteger*>(&data[inx]), 0 }); move(); } bool _move() { inx++; if (inx >= data.size()) return false; stk.push({ const_cast<NestedInteger*>(&data[inx]), 0 }); return move(); } bool move() // to make sure we always point to a Integer { if (stk.empty()) { return _move(); } NestedInteger *p = stk.top().first; unsigned inx = stk.top().second; // Pop all done-lists if (!p->isInteger() && p->getList().size() == inx) { stk.pop(); if (!stk.empty()) { stk.top().second++; return move(); } return _move(); } if (!stk.empty()) { const vector<NestedInteger> &list = stk.top().first->getList(); for (unsigned i = stk.top().second; i < list.size(); i ++) { if (list[i].isInteger()) { stk.push({ const_cast<NestedInteger*>(&list[i]), 0 }); return true; } else { stk.push({ const_cast<NestedInteger*>(&list[i]), 0 }); if (move()) return true; } } } return false; } int next() { NestedInteger *top = stk.top().first; //assert (top->isInteger()) int ret = top->getInteger(); stk.pop(); if (!stk.empty()) stk.top().second++; move(); return ret; } bool hasNext() { return !stk.empty(); } };