📜  初学者的算法实践问题套装1

📅  最后修改于: 2021-04-23 19:06:59             🧑  作者: Mango

考虑下面的C函数。

unsigned fun(unsigned n)
{
    if (n == 0) return 1;
    if (n == 1) return 2;
  
    return fun(n-1) + fun(n-1);
}

对于上面的代码,请考虑以下问题,而忽略编译器的优化。
a)上面的代码有什么作用?
b)以上代码的时间复杂度是多少?
c)可以降低上述函数的时间复杂度吗?

fun(n)有什么作用?
在上面的代码中,fun(n)等于2 * fun(n-1)。因此,上面的函数返回2 n 。例如,对于n = 3,它返回8;对于n = 4,它返回16。

fun(n)的时间复杂度是多少?
以上函数的时间复杂度是指数的。令时间复杂度为T(n)。 T(n)可以写成下面的递归。 C是机器相关的常数。

T(n) = T(n-1) + T(n-1) + C
     = 2T(n-1) + C 

上述重复的解为Θ(2 n )。我们可以通过递归树法解决它。递归树将是高度为n的二叉树,除最后一个级别外,每个级别都将完全填满。

C
                  /        \
               C              C
            /     \         /     \
          C        C       C        C  
         / \      / \     / \      / \
        .  .     .   .   .   .    .   .
        .  .     .   .   .   .    .   .
       Height of Tree is Θ(n)

可以减少fun(n)的时间复杂度吗?
减少时间复杂度的一种简单方法是拨打一个电话而不是2个电话。

unsigned fun(unsigned n)
{
    if (n == 0) return 1;
    if (n == 1) return 2;
      
    return 2*fun(n-1);
}

上述解决方案的时间复杂度为Θ(n)。 T令时间复杂度为T(n)。 T(n)可以写成下面的递归。 C是机器相关的常数。

T(n) = T(n-1) + C

我们可以通过递归树法解决它。递归树将是高度为n的偏斜二叉树(每个内部节点只有一个孩子)。

C
           /
          C
         /
        C
       /
      .  
    .
 Height of Tree is Θ(n)

可以使用分而治之技术来进一步优化上述函数,以计算功效。

unsigned fun(unsigned n)
{
    if (n == 0) return 1;
    if (n == 1) return 2;
    unsigned x = fun(n/2);
    return (n%2)? 2*x*x: x*x;
}

上述解决方案的时间复杂度为Θ(Logn)。令时间复杂度为T(n)。 T(n)可以近似地写成下面的递归。 C是机器相关的常数。

T(n) = T(n/2) + C

我们可以通过递归树法解决它。递归树将是高度为Log(n)的偏斜二叉树(每个内部节点只有一个子节点)。

C       
           /
          C
         /
        C
       /
      .  
    .
 Height of Tree is Θ(Logn)

我们还可以使用按位左移运算符'<

unsigned fun(unsigned n)
{
   return 1 << n;
}