# [341. Flatten Nested List Iterator](https://leetcode.com/problems/flatten-nested-list-iterator/) # 思路 这道题让我们将嵌套链表压平。 ## 思路一 思路很简单,因为链表的元素可能还是链表,所以是个递归(或者用栈转成非递归),我们先创建一个记录压平后所有元素的全局数组nums, 然后定义helper递归函数,传入一个`NestedInteger`记为`nest`: * 若`nest.isInteger() == True`,即`nest`是个数,将`nest.getInteger()`push进nums即可; * 否则,即`nest`是个列表,那么对`nest.getList()`的每个元素递归调用helper。 NestedIterator构造函数里面,我们对nestedList每个元素调用一下`helper`以建立nums,建立好nums后,`hasNext()`和`next()`就好写了。 ## 思路二 思路一是提前将链表压平,用一个数组存放压平后的元素。这样对空间复杂度要求比较高,如果能在每次调用`next()`的过程中进行压平,就不需要用一个数组来存放压平后的元素了。 总体思路是用一个栈,栈里的元素是一个pair: `pair::iterator, vector::iterator>`,表示尚未访问的某个`NestedInteger`数组的始末迭代器;然后还需要用两个迭代器变量`start`和`end`记录当前正在访问的位置即终点位置,在访问每个元素的过程中: * 如果`start == end`,说明正在访问的位置到达了终点,应该将其更新为栈顶的元素,然后递归访问; * 否则,若`start -> isInteger() == True`,即是个数,则返回这个数即可,然后迭代器`start`后移一个位置; * 否则,即是个列表,那么需要把当前的`start`和`end`入栈,然后将`start`和`end`更新为这个列表的`begin()`和`end()`,再递归进行访问; 需要注意的是,为了处理`[[]]`这种情况,我们采用提前用一个变量`next_val`记录下一个应该访问的值,还要用一个bool变量`valid_next`标记`next_val`所记录的值是否是有效的。那么`hasNext()`只需返回`valid_next`即可。 # C++ ## 思路一 ``` C++ class NestedIterator { private: int cur_index, size; vectornums; void helper(NestedInteger &nest){ if(nest.isInteger()) nums.push_back(nest.getInteger()); else{ auto &list = nest.getList(); for(auto &a: list) helper(a); } } public: NestedIterator(vector &nestedList) { cur_index = 0; for(auto & a: nestedList) helper(a); size = nums.size(); } int next() { return nums[cur_index++]; } bool hasNext() { return cur_index < size; } }; ``` ## 思路二 ``` C++ class NestedIterator { private: stack< pair::iterator, vector::iterator> >stk; vector::iterator start; vector::iterator end; int next_val; // 存放了调用next()应该返回的值 bool valid_next; // next_val中存放的值是否是有效的 public: NestedIterator(vector &nestedList) { start = nestedList.begin(); end = nestedList.end(); valid_next = true; next_val = DFS(); } int DFS() { if(start == end){ if(stk.empty()) { valid_next = false; return -1; // 无效的next_val } start = stk.top().first; end = stk.top().second; stk.pop(); return DFS(); } if(start -> isInteger()){ int res = start -> getInteger(); start++; return res; } else{ auto new_start = (start -> getList()).begin(); auto new_end = (start -> getList()).end(); start++; if(start != end) stk.push({start, end}); start = new_start; end = new_end; return DFS(); } } int next(){ int tmp = next_val; next_val = DFS(); return tmp; } bool hasNext() { return valid_next; } }; ```