LeetCode/solutions/341. Flatten Nested List Iterator.md
2020-08-19 22:23:34 +08:00

120 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# [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<vector<NestedInteger>::iterator, vector<NestedInteger>::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;
vector<int>nums;
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<NestedInteger> &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<vector<NestedInteger>::iterator, vector<NestedInteger>::iterator> >stk;
vector<NestedInteger>::iterator start;
vector<NestedInteger>::iterator end;
int next_val; // 存放了调用next()应该返回的值
bool valid_next; // next_val中存放的值是否是有效的
public:
NestedIterator(vector<NestedInteger> &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;
}
};
```