第二种算法是如何变得比第一种算法更高效的?在第二种方法中,子阵列的右侧是如何移动的
How has the second algorithm become more efficient than the first one and how is the right side of the subarray moving in the second algorithm?
问题-给定一个n个数字的数组,我们的任务是计算最大子数组和,即大堆当数组中可能存在负值时,问题就很有趣了。数组={-1,2,4,-3,5,2,-5,2}。
第一种算法-
int best = 0;
for (int a = 0; a < n; a++) {
for (int b = a; b < n; b++) {
int sum = 0;
for (int k = a; k <= b; k++) {
sum += array[k];
}
best = max(best,sum);
}
}
cout << best << "n";
第二种算法-
int best = 0;
for (int a = 0; a < n; a++) {
int sum = 0;
for (int b = a; b < n; b++) {
sum += array[b];
best = max(best,sum);
}
}
cout << best << "n";
这就是书中所说的-通过从算法1中删除一个循环,可以很容易地提高算法1的效率子阵列移动。
在第二种算法中,子阵列的右端是如何移动的,有人能向我解释一下吗?
第一个版本对从索引a
到索引b
的子数组的所有子数组和进行强力比较,让我们将这些子数组和称为subsum(a,b)
。
第二个版本也是相当暴力的,但使用了subsum(a,b+1) == subsum(a,b) + array[b+1]
。
换句话说:要知道第一个元素(比如10
元素(的和,可以使用之前计算的第一个9
元素的和。如果你想用笔和纸来解决这个问题,这将是显而易见的,但第一个版本并没有做到这一点。相反,第一个版本对于a
和b
的所有组合都有两个嵌套循环,并且总是以新的sum = 0
开始,这相当浪费。
只考虑第一个版本的外循环:
for (int a = 0; a < n; a++) {
for (int b = a; b < n; b++) {
int sum = 0;
// ...
}
}
这里CCD_ 10计算CCD_。
在第二个版本中:
int best = 0;
for (int a = 0; a < n; a++) {
int sum = 0;
for (int b = a; b < n; b++) {
sum += array[b];
best = max(best,sum);
}
}
外循环负责在不同的"时间"启动子阵列;左端";。而内环";移动";";右端";。
内环体计算CCD_ 12和内环的下一次迭代"CCD_;移动";13到下一个索引以使用上述关系式计算CCD_ 14:CCD_。由于CCD_ 16固定在内循环中;移动右端";。
相关文章:
- 为什么一种算法在相同的时间复杂度下比另一种算法更快?
- 是否有一种 STL 算法可以最后找到,但它也适用于指针?
- C++/STL 我应该使用哪种算法来检查容器是否有重复项?
- 字符串::find在c++中使用了哪种算法
- 尝试实现二叉搜索算法,似乎无法使其工作
- 如何将 numpy 二维数组作为一种可以用C++读取的二进制格式存储在磁盘上
- 如何计算摘要/将使用哪种算法?
- 我是 c++ 的新手,有没有一种算法可以找到 3d 数组中最接近的 0 的距离?
- 有人可以给我提供二维二元索引树的算法吗?
- 有没有一种算法可以将 LAPACK 排列更改为真正的排列?
- 为什么"quick sorting"算法的这两种变体在性能上差异如此之大?
- 这是河内算法的递归塔是一种不知情的搜索
- 有没有一种方法可以使用弗洛伊德-沃歇尔算法给出最短路径,其中存在负权重循环而不允许重叠边缘?
- 如何测试两种算法并确定哪种算法更快
- 如何编写一种算法,该算法在哪个行中显示出在哪个行中显示(我使用的是std :: map)
- 了解一种神秘地起作用的递归二进制搜索算法
- 理解算法二叉搜索背后的工作原理C++问题
- 质数搜索算法(两种不同的算法)和Prime表的使用
- 多个数组中的排序算法;二叉搜索功能
- 是否存在一种算法来确定二维空间中的一组点是否形成一个封闭区域