• [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====
    ", _it);
                    delete _sub;
                    printf("%p====
    ", _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
    
  • 相关阅读:
    Plugs介绍(翻译) .net/C#开源操作系统学习系列六
    Cosmos的里程碑2(Mile Stone 2)之浅尝PCI总线、设备编程.net/C#开源操作系统学习系列九
    [翻译] WindowsPhoneGameBoy模拟器开发二Rom文件分析
    Cosmos开篇、本系列目录.net/C#开源操作系统学习系列一
    Cosmos的汇编级调试器(翻译) .net/C#开源操作系统学习系列七
    数据库牛人榜(随时更新)
    redis大key删除
    Linux LVM硬盘管理及LVM扩容
    Linux学习之CentOS(十一)CentOS6.4下Samba服务器的安装与配置
    Linux学习之CentOS(三十)SELinux安全系统基础
  • 原文地址:https://www.cnblogs.com/zhcpku/p/15305102.html
Copyright © 2020-2023  润新知