首页 > 解决方案 > 这种重现的时间复杂度?

问题描述

我试图使用主定理来计算这种递归的运行时复杂性。根据主定理,我对此有点迷茫。

T(n)=aT(n/b))+f(n)

我插入值

有多少递归(拆分)函数?

a = 1

相对子问题大小。输入减少的速率是多少?

b = L 因为子问题是独立列表

运行时在递归之外完成的工作?

f(n) = n 例如可能没有列表只有整数

主定理的哪种情况适用于此?

/*
341. Flatten Nested List Iterator on leetcode
 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.

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].
*/

void recurse(vector<NestedInteger>& nestedList){
    for(int i = 0 ; i < nestedList.size(); i++){
        if(nestedList[i].isInteger()){
            res.push_back(nestedList[i].getInteger());
        }else{
            recurse(nestedList[i].getList());
        }

    }
}

标签: algorithmperformancerecursiontime-complexity

解决方案


这个特殊的递归问题没有使用主定理很好地建模。主定理适用于递归关系,其中输入的大小在每次递归调用时都会缩小某个常数因子。在你的情况下,这不一定是真的。例如,考虑扁平化这个列表:

[[[[[[[[...[[[1]]]...]]]]]]]]]

在这里,每个递归调用只是将列表的大小减一,而不是除以某个常数。结果,你不能在这里应用主定理。

我认为,如果您重新构建列表表示的方式,您可能会更幸运地分析此递归。您可以将列表视为二叉树,其中列表表示为向右移动的节点链,而子列表表示为左子树。因此,例如,输入

[1, [2, 3], [[4]]

看起来像这样:

 1
  \
   *
  / \
 2   \
  \   \
   3   *
      /
     *
    /
   4

您的递归算法在访问节点时执行 O(1) 工作,加上处理右子树(列表的其余部分)和左子树(递归列表,假设项目是列表)所需的工作。从这个意义上说,你访问二叉树中的每个节点一次,每个节点做 O(1) 的工作,总共 O(n) 的工作。


推荐阅读