2 ^ n的大O的例子

时间:2016-01-21 05:14:29

标签: algorithm big-o time-complexity

所以我可以想象一个算法是什么,它具有n ^ c的复杂性,只是嵌套for循环的数量。

for (var i = 0; i < dataset.len; i++ {
    for (var j = 0; j < dataset.len; j++) {
        //do stuff with i and j
    }
}

日志是每次将数据集分成两半的东西,二进制搜索会这样做(不完全确定这个代码是什么样的)。

但是什么是c ^ n或更具体地2 ^ n的算法的简单示例。 O(2 ^ n)是基于数据循环吗?或者如何拆分数据?或完全不同的东西?

8 个答案:

答案 0 :(得分:22)

运行时间为O(2 ^ N)的算法通常是递归算法,通过递归求解大小为N-1的两个较小问题来解决大小为N的问题。

这个程序,例如打印出所有必要的动作,以解决伪代码中N盘的着名“河内塔”问题

void solve_hanoi(int N, string from_peg, string to_peg, string spare_peg)
{
    if (N<1) {
        return;
    }
    if (N>1) {
        solve_hanoi(N-1, from_peg, spare_peg, to_peg);
    }
    print "move from " + from_peg + " to " + to_peg;
    if (N>1) {
        solve_hanoi(N-1, spare_peg, to_peg, from_peg);
    }
}

设T(N)为N个磁盘所需的时间。

我们有:

T(1) = O(1)
and
T(N) = O(1) + 2*T(N-1) when N>1

如果您反复扩展上一学期,则会得到:

T(N) = 3*O(1) + 4*T(N-2)
T(N) = 7*O(1) + 8*T(N-3)
...
T(N) = (2^(N-1)-1)*O(1) + (2^(N-1))*T(1)
T(N) = (2^N - 1)*O(1)
T(N) = O(2^N)

要实际解决这个问题,您只需要知道递归关系中的某些模式会导致指数结果。通常T(N) = ... + C*T(N-1) C > 1表示O(x ^ N)。参见:

https://en.wikipedia.org/wiki/Recurrence_relation

答案 1 :(得分:10)

考虑一下迭代集合的所有可能子集。例如,这种算法用于广义背包问题。

如果你发现很难理解迭代子集如何转换为O(2 ^ n),想象一组n个开关,每个开关对应一个集合的一个元素。现在,每个开关都可以打开或关闭。将“on”视为属于子集。注意,可能有多少种组合:2 ^ n。

如果你想在代码中看到一个例子,在这里考虑递归通常会更容易,但我现在不能想到任何其他好的和可理解的例子。

答案 2 :(得分:1)

  int Fibonacci(int number)
 {
  if (number <= 1) return number;

  return Fibonacci(number - 2) + Fibonacci(number - 1);
 }

每增加一个输入数据集,增长率就会翻倍。 O(2N)函数的增长曲线是指数 - 从非常浅的开始,然后是气象上升。 我的大O(2 ^ n)的例子,但更好的是:

public void solve(int n, String start, String auxiliary, String end) {
   if (n == 1) {
       System.out.println(start + " -> " + end);
   } else {
       solve(n - 1, start, end, auxiliary);
       System.out.println(start + " -> " + end);
       solve(n - 1, auxiliary, start, end);
   }

在此方法程序中打印所有动作以解决“河内塔”问题。 这两个例子都使用递归来解决问题并且运行时间很长(<^ ^ n)。

答案 3 :(得分:1)

请考虑您要猜测的智能手机的PIN(您关心的人),此PIN是4位整数。您知道保存4位数字的最大位数是14位,2 ^ 14是16384。因此,您将不得不猜测此PIN的值,即14位正确的组合。 >

一种方法是问问信任您的朋友并将其交给您。另一种方法是蛮力。因此,为简单起见,请考虑一下您想正确猜出的一个简单的2位单词,每个位都有2个可能的值,即0或1。因此,所有可能性都是:

00
01
10
11

从逻辑电路设计中我们知道,n位字的所有可能性都是2 ^ n种可能的组合。所以2 ^ 2是我们前面看到的4种可能的组合。

14位整数PIN也是如此,因此猜测PIN将需要您解决2 ^ 14可能的结果难题,因此需要一种时间复杂度O(2 ^ n)的算法。

因此,那些类型的问题(其中集合S中的元素组合不同),并且您将不得不尝试通过尝试所有可能的组合来解决问题,这些问题的复杂度为O(2 ^ n)。但是,乘幂的底数不必为2。在上面的示例中,它的底数为2,因为每个元素(每个位)都有两个可能的值,而在其他问题中则不会。

O(2 ^ n)算法的另一个很好的例子是递归背包。无论您是否采用它,都必须尝试不同的组合以最大化该值,而集合中的每个元素都有两个可能的值。

Edit Distance问题的时间复杂度为O(3 ^ n),因为您需要为n个字符串,删除,插入或替换中的每个字符串选择3个决定。

答案 4 :(得分:0)

c ^ N =来自n大小字母的c元素的所有组合。

更具体地说,2 ^ N是所有可用N位表示的数字。

常见情况是递归实现的,例如:

vector<int> bits;
int N
void find_solution(int pos) {
   if (pos == N) {
     check_solution();
     return;
   }
   bits[pos] = 0;
   find_solution(pos + 1);
   bits[pos] = 1;
   find_solution(pos + 1);
}

答案 5 :(得分:0)

这是一个代码片段,用于计算商品数组中每个值组合的值和(并且value是一个全局数组变量):

fun boom(idx: Int, pre: Int, include: Boolean) {
    if (idx < 0) return
    boom(idx - 1, pre + if (include) values[idx] else 0, true)
    boom(idx - 1, pre + if (include) values[idx] else 0, false)
    println(pre + if (include) values[idx] else 0)
}

正如您所看到的,它是递归的。我们可以插入循环以获得Polynomial复杂性,并使用递归来获得Exponential复杂性。

答案 6 :(得分:0)

以下是使用Big O / Landau(2 ^ N)的python中的两个简单示例:

javascript: var lingq_base_url = %27https://www.lingq.com%27;(function()%7B(function()%7Bvar b=function()%7Bwindow.lingq_bookmarklet%3Flingq_bookmarklet():window.setTimeout(b,500)%7D,c=document.getElementsByTagName("head")%5B0%5D,a=document.createElement("script");a.setAttribute("type","text/javascript");a.setAttribute("src",lingq_base_url+"/bookmarklet/bookmarklet.js");c.appendChild(a);b()%7D)()%7D)()

答案 7 :(得分:0)

假设一个集合是它自己的一个子集,那么对于一个有 n 个元素的集合,有 2ⁿ 个可能的子集。

这样想。要制作一个子集,让我们取一个元素。此元素在您创建的子集中有两种可能性:存在或不存在。这同样适用于集合中的所有其他元素。将所有这些可能性相乘,得到 2ⁿ。