[LeetCode 341.] 扁平化嵌套列表迭代器

LeetCode 341. 扁平化嵌套列表迭代器

题目描述

给你一个嵌套的整数列表 nestedList 。每个元素要么是一个整数,要么是一个列表;该列表的元素也可能是整数或者是其他列表。请你实现一个迭代器将其扁平化,使之能够遍历这个列表中的所有整数。

实现扁平迭代器类 NestedIterator :

  • NestedIterator(List nestedList) 用嵌套列表 nestedList 初始化迭代器。
  • int next() 返回嵌套列表的下一个整数。
  • boolean hasNext() 如果仍然存在待迭代的整数,返回 true ;否则,返回 false 。
    你的代码将会用下述伪代码检测:
initialize iterator with nestedList
res = []
while iterator.hasNext()
    append iterator.next() to the end of res
return res

如果 res 与预期的扁平化列表匹配,那么你的代码将会被判为正确。

示例 1:

输入:nestedList = [[1,1],2,[1,1]]
输出:[1,1,2,1,1]
解释:通过重复调用 next 直到 hasNext 返回 false,next 返回的元素的顺序应该是: [1,1,2,1,1]。

示例 2:

输入:nestedList = [1,[4,[6]]]
输出:[1,4,6]
解释:通过重复调用 next 直到 hasNext 返回 false,next 返回的元素的顺序应该是: [1,4,6]。

提示:

  • 1 <= nestedList.length <= 500
  • 嵌套列表中的整数值在范围 [-106, 106] 内

解题思路

这道题的基本思想仍然是递归。对于一个列表,是否存在下一个元素,要看当前迭代器位置,如果是一个数字的话,直接可以判断,如果是一个列表如何判断呢?
给这个列表创建一个子迭代器,在这个迭代器里判断就可以了!

参考代码

错误代码

刚开始可能写出这种代码,但是遇到 [1,[2,3]] 这种需要连续推出的嵌套,会报内存错误。主要原因在于,我们的使用方法是 while(it.hasNext()) it.next(); 没有正确维护 it 状态。

class NestedIterator {
    vector<NestedInteger>::iterator _it;
    vector<NestedInteger>::iterator _end;
    NestedIterator *_sub;
public:
    NestedIterator(vector<NestedInteger> &nestedList) {
        _it = nestedList.begin();
        _end = nestedList.end();
        _sub = nullptr;
    }
    
    int next() {
        if (_it->isInteger()) {
            int val = _it->getInteger();
            _it++;
            return val;
        }

        if (_sub == nullptr) {
            _sub = new NestedIterator(_it->getList());
        }
        if (_sub->hasNext()) {
            return _sub->next();
        } else {
            delete _sub;
            _sub = nullptr;
            _it++;
            return next();
        }
    }
    // // 注意到题目中 1 <= nestedList.length,所以不担心列表元素是空的
    bool hasNext() {
        return _it != _end;
    }
};

正确代码

注意到我们的 it 始终放在下一次访问的元素位置上,访问子序列时也应该维护这一性质,即:hasNext 来判断是否存在下一个合法元素,next 一定是直接拿到合法元素。

而且,题目中欺骗了我们,题目说 1 <= nestedList.length <= 500 然而测试样例却给了一个 [[]] ,他难道是认为 nestedList 中的 nestedList 不算 nestedList 吗 ……

几个测试样例,分别用于测试不同的边界情况:
[1,2,3]
[[1,2],3]
[1,[2,3]]
[[]]
[[[[]]]

/*
 * @lc app=leetcode.cn id=341 lang=cpp
 *
 * [341] 扁平化嵌套列表迭代器
 */

// @lc code=start
/**
 * // 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 {
    vector<NestedInteger>::iterator _it;
    vector<NestedInteger>::iterator _end;
    NestedIterator *_sub;
public:
    NestedIterator(vector<NestedInteger> &nestedList) {
        _it = nestedList.begin();
        _end = nestedList.end();
        _sub = nullptr;
    }

    int next() {
        if (_it->isInteger()) {
            int val = _it->getInteger();
            _it++;
            return val;
        }
        return _sub->next();
    }

    bool hasNext() {
        while (_it != _end) {
            if (_it->isInteger()) {
                return true;
            }
            if (_sub == nullptr) {
                _sub = new NestedIterator(_it->getList());
            }
            if (_sub->hasNext()) {
                return true;
            } else {
                printf("%p====\n", _it);
                delete _sub;
                printf("%p====\n", _it);

                _sub = nullptr;
                _it++;
            }
        }
        return false;
    } // AC
};

/**
 * Your NestedIterator object will be instantiated and called as such:
 * NestedIterator i(nestedList);
 * while (i.hasNext()) cout << i.next();
 */
// @lc code=end
posted @ 2021-09-17 16:08  与MPI做斗争  阅读(77)  评论(0编辑  收藏  举报