LintCode T22 列表扁平化

124 阅读3分钟

考察内容:递归

时间:2020-08-31 星期一

作者:guuzaa

掘金主页:🌏


题目描述 📃

题目链接 🔗

题目给定一个列表(数组),列表中的元素可能是整数也可能是一个列表。题目要求是将这个列表转换成只包含整数的列表。

分析 💻

假设将一个列表表示为树的根,整数表示为一个叶子节点。那么题目给定的一个列表可以用树画出(如下图)。而扁平化就是将这棵树转换成一个顺序表。

树结构
树结构

递归实现

这是一个可以用递归求解的题目。大致思路也很简单:先开一个列表用来保存结果,然后遍历列表中的元素,如果元素是整数就把它插入到结果列表中,否则继续分解该列表。

Python 实现
def flatten(self, nestedList: List[List[int]]) -> List[int]:
    if isinstance(nestedList, int):
        return [nestedList]
    res = []
    for ele in nestedList:
        res.extend(self.flatten(ele))
       
    return res
C++ 实现
// 接口
class NestedInteger {
   public:
     bool isInteger() const// 判断是否是整数
     int getInteger() const// 如果是整数,返回该整数。否则是NULL
     const vector<NestedInteger> &getList() const// 返回元素中的列表,如果元素不是列表返回NULL
};

vector<intflatten(vector<NestedInteger> nestedList) {
    vector<int> res;
    for (auto item : nestedList) {
        if(item.isInteger()) res.push_back(item.getInteger());
        else {
            auto sub_list = item.getList();
            res.insert(res.end(), sub_list.begin(), sub_list.end());
        }
    }
    return res;
}
时空复杂度分析

时间复杂度 O(N),空间复杂度 O(N)

非递归实现

转变思路,用栈模拟递归调用栈。因为栈是后进先出的,所以先逆序将给定列表存到栈里(这样确保栈顶是列表的第一个元素)。然后循环遍历栈顶元素直到栈空。遇到栈顶元素是列表时,把列表元素逆序放到栈顶;栈顶元素是整数时,将它放到结果列表中。

C++ 实现
vector<int> flatten(vector<NestedInteger> &nestedList) {
    vector<int> res;
    stack<NestedInteger> st;
    for(auto it = nestedList.rbegin(); it != nestedList.rend(); it++) st.push(*it);

    while(!st.empty()) {
        NestedInteger ele = st.top();
        st.pop();
        if(ele.isInteger()) {
            res.push_back(ele.getInteger());
        } else {
            auto sub_list = ele.getList();
            for(auto it = sub_list.rbegin(); it != sub_list.rend(); it++)
                st.push(*it);
        }
    }

    return res;
}
时空复杂度分析

时间复杂度 O(N),空间复杂度 O(N)

总结 📕:

  • 自己对递归掌握的特别不好,拿到这道题目完全没有思路,日后需要继续加强。
  • 方法并不是很好,如果大家有一些好的方法,欢迎留言。

全文完