所以我可以想象一个算法是什么,它具有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)是基于数据循环吗?或者如何拆分数据?或完全不同的东西?
答案 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)。参见:
答案 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ⁿ。