当前位置: 首页 > 知识库问答 >
问题:

寻找生成所有子集问题的回溯解的时间复杂度

经兴安
2023-03-14

给定不同整数的问题,生成所有子集。https://www.interviewbit.com/problems/subset/

我找到了两种解决方案。

第一个解决方案::

 void helper_subsets(vector<vector<int>> &res , vector<int> &A , 
    vector<int> &subset ,int current)
{
    if(current == A.size())
        res.push_back(subset) ;
    else
    {
        helper_subsets(res,A,subset,current+1) ;
        subset.push_back(A[current]) ;
        helper_subsets(res,A,subset,current+1) ;
        subset.pop_back() ;
    }
}

vector<vector<int> >subsets(vector<int> &A) {
    vector<vector<int>> res ;

    sort(A.begin(),A.end()) ;

    vector<int> subset ;

    helper_subsets(res , A , subset , 0 ) ;

    sort(res.begin(),res.end()) ;
    return res ;
}

第二种解决方案

void helper_subsets(vector<vector<int>> &res , vector<int> &A , 
    vector<int> &subset ,int current)
{
    res.push_back(subset) ;
    for(int i = current ; i < A.size() ; i++)
    {
        subset.push_back(A[i]) ;
        helper_subsets(res,A,subset,i+1) ;
        subset.pop_back() ;
    }
}

vector<vector<int> > subsets(vector<int> &A) {
    vector<vector<int>> res ;

    sort(A.begin(),A.end()) ;

    vector<int> subset ;

    helper_subsets(res , A , subset , 0 ) ;

    sort(res.begin(),res.end()) ;
    return res ;
}

t(n)=2t(n-1)c(即2个大小为n-1的递归调用,每个n都有一些恒定的时间)t(n)=O(2^n)通过解决上述递归关系。

但对于第二个解,我无法定义递归关系以最终使用反向替换来获得时间复杂度,并且无法通过递归树方法获得时间复杂度。请帮我找到第二个解的时间复杂度。

共有1个答案

淳于亦
2023-03-14

问题2的类似递归关系为:

       n - 1
T(n) =   Σ  T(n - i) + c
       i = 1

–从当前到A.size()的循环。要解决此问题,请展开第一项:

T(n) = T(n - 1) + T(n - 2) + T(n - 3) + ... + T(1) + c
       --------
           |
     =     |      T(n - 2) + T(n - 3) + ... + T(1) + c +
            --->  T(n - 2) + T(n - 3) + ... + T(1) + c

     = 2 * [T(n - 2) + T(n - 3) + ... + T(1) + c]
     = 2 * T(n - 1)

即,一个非常相似的递归关系,仅相差一个常数。它仍然计算为O(2^n),基本情况为T(1)=O(1)

 类似资料:
  • 给定一个高度为h的二叉查找树(BST),它需要O(k h)时间来连续应用BST Inorder后续算法k次,从任何节点开始,在先前调用返回的节点上应用每个下一个调用。 伪代码: 我如何证明这种时间复杂性? 特别是,我试图建立k和访问的节点数之间的关系,但在这里找不到任何模式。

  • 如何计算这些回溯算法的时间复杂度,它们是否具有相同的时间复杂度?如果不一样怎么办?请详细解释并感谢您的帮助。 我实际上有点困惑,对于断字(b),复杂度是O(2n),但对于哈密顿循环,复杂度是不同的,对于打印相同字符串的不同排列,以及对于解决n皇后问题,复杂度是不同的。

  • 我试图对非相邻元素的最大和进行动态规划回溯,以构造得到最大和的最优解。 假设输入列表为[1,2,3,4,5] 回忆录应为[1,2,4,6,9] 我的最大值是9,对吗? > 我发现第一次出现备忘录中的最大总和(因为我们可能不会选择最后一项)[this is O(N)] 然后我找到使用此公式选择的前一项:

  • 对于回溯算法,计算空间(堆栈空间)和时间复杂度的好方法是什么? 我们希望输出组合的长度正好是K,并且sol集必须是唯一的 输入:arr:[1,2,3,4,5]k:4 输出: [1,2,3,4]//[2,1,3,4]无效,因为它==[1,2,3,4] 最差的时间复杂度是O(n^k),其中n是数组的长度。

  • 我正在尝试实现DFS回溯算法,该算法涉及利用维基百科上的堆栈(而不是递归算法)。我试图生成一个由0和1组成的迷宫,其中1代表一堵墙,0代表一条可用路径。对于迷宫中不是墙的任何给定空间,必须始终有一条有效的路径,可以从任何其他非墙单元格到达。 我从一个迷宫开始,它是一个二维大小的迷宫阵列[15][20],然后按照算法将需要标记为已正确访问的单元格标记为已访问。最初,所有单元格(不包括外部边框)都标记

  • 我的问题是,我需要从这个布尔数组中提取和等于指定和的实际子集。我尝试过这样做,但是我的方法中的逻辑(涉及到使用布尔数组来减少我必须分析的子集的数量)变得相当复杂,并且我很难实现它。 有没有人知道当使用生成的布尔数组时,找到其和等于给定和的所有子集的好方法? 编辑%1 输入 输出