【leetcode】【medium】341. Flatten Nested List Iterator

感情迁移 提交于 2020-02-13 13:08:34

341. Flatten Nested List Iterator

Given a nested list of integers, implement an iterator to flatten it.

Each element is either an integer, or a list -- whose elements may also be integers or other lists.

Example 1:

Input: [[1,1],2,[1,1]]
Output: [1,1,2,1,1]
Explanation: By calling next repeatedly until hasNext returns false, 
             the order of elements returned by next should be: [1,1,2,1,1]

Example 2:

Input: [1,[4,[6]]]
Output: [1,4,6]
Explanation: By calling next repeatedly until hasNext returns false, 
             the order of elements returned by next should be: [1,4,6]

题目链接:https://leetcode-cn.com/problems/flatten-nested-list-iterator/

 

解题思路

从类的调用效率来看,有2种设计:

设计一:时间均衡

构造时只做初步拆解,在调用hasNext时进一步拆。

一边拆解一边调用,运行时间较分散。

设计二:头重脚轻

在构造时完成所有拆解。

构造费时,调用快。

 

从拆解方法上,有2中方法:

法一:递归

将对list的拆解写成函数,遇到list则向下调用。

法二:非递归,栈

将list逆向压入栈,不断取栈顶解析。

 

结合设计和方法,思考如何实现代码:

设计一+法二:递归一条道走到黑,和拆分时间的思想不一致。

设计二+法一:递归和一股脑拆解完的思路不谋而合;递归中已经使用了栈来存储临时状态,没有必要再去设计栈。

 

代码实现

设计一+法二

注意:压栈时需要对vector里的元素逆着取。

/**
 * // 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 {
    stack<NestedInteger> record;
public:
    NestedIterator(vector<NestedInteger> &nestedList) {
        if(nestedList.empty()) return;
        for(auto iter=nestedList.rbegin(); iter!=nestedList.rend(); ++iter){
            record.push(*iter);
        }
    }

    int next() {
        auto tmp = record.top();
        record.pop();
        return tmp.getInteger();
    }

    bool hasNext() {
        while(!record.empty()){
            auto tmp = record.top();
            if(tmp.isInteger()){
                return true;
            }
            record.pop();
            auto tmplist = tmp.getList();
            for(auto iter=tmplist.rbegin(); iter!=tmplist.rend(); ++iter){
                record.push(*iter);
            }
        }
        return false;
    }
};

/**
 * Your NestedIterator object will be instantiated and called as such:
 * NestedIterator i(nestedList);
 * while (i.hasNext()) cout << i.next();
 */

 

设计二+法一

/**
 * // 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<int> record;
    int idx;
public:
    NestedIterator(vector<NestedInteger> &nestedList) {
        if(nestedList.empty()) return;
        flaten(nestedList);
        idx = 0;
    }

    void flaten(vector<NestedInteger> &list){
        for(auto iter=list.begin(); iter!=list.end(); ++iter){
            if((*iter).isInteger()){
                record.push_back((*iter).getInteger());
            }else{
                flaten((*iter).getList());
            }
        }
    }

    int next() {
        return record[idx++];
    }

    bool hasNext() {
        if(idx<record.size()) return true;
        else return false;
    }
};

/**
 * Your NestedIterator object will be instantiated and called as such:
 * NestedIterator i(nestedList);
 * while (i.hasNext()) cout << i.next();
 */

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!