对不起,我有一个任务要用蛮力算法O(n^2)、分治算法O(nlogn)和Kadane算法O(n)来解决最大子数组问题。(我的代码不同)。
#include <iostream>
int DivideAndConquer(int[], int);
int main()
{
// Example 1
//const int MyArraySize = 16;
//int MyArray[MyArraySize] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7 }; // answer: Index 7 -> 10, sum = 43
// Example 2
const int MyArraySize = 8;
int MyArray[MyArraySize] = { -2, -5, 6, -2, -3, 1, 5, -6 }; // answer: Index 2 -> 6, sum = 7
int FinalResult;
FinalResult = DivideAndConquer(MyArray, MyArraySize);
std::cout << "Using Divide And Conquer: With O(nlogn) Sum = " << FinalResult << "\n\n";
system("pause");
return 0;
}
int DivideAndConquer(int* _myArray, int _myArraySize)
{
if (_myArraySize == 1)
return _myArray[0];
int middle = _myArraySize / 2;
int Result_LeftPortion = DivideAndConquer(_myArray, middle);
int Result_RightPortion = DivideAndConquer(_myArray + middle, _myArraySize - middle);
int LeftSum = -9999;
int RightSum = -9999;
int TotalSum = 0;
for (int i = middle; i < _myArraySize; i++)
{
TotalSum += _myArray[i];
RightSum = TotalSum < RightSum ? RightSum : TotalSum;
}
TotalSum = 0;
for (int i = middle - 1; i >= 0; i--)
{
TotalSum += _myArray[i];
LeftSum = TotalSum < LeftSum ? LeftSum : TotalSum;
}
int PartialResult = LeftSum < RightSum ? RightSum : LeftSum;
int Result= (PartialResult < LeftSum + RightSum ? LeftSum + RightSum : PartialResult);
return Result;
}
你的算法有逻辑问题,它不是最优的。您甚至没有使用result_leftpartes
、result_rightpartes
值。最终结果始终是整个数组的rightsum
、leftsum
和totalsum
的最大值。所有其他子数组的值将被忽略。
用分而治之的方法解决这个问题的方法如下。应该为每个子数组保存四个值:
sub_left.s_r range is (2,5)
sub_right.t range is (6,10)
if ( sub_right.t + sub_left.s_r > sub_right.s_r )
s_r range = (2,10)
这是我的实现:
#include <iostream>
using namespace std;
struct node {
//value, right index, left index
int value, r, l;
node(int _v, int _r, int _l){
value = _v;
r = _r;
l = _l;
}
node (){}
};
struct sub {
// max node containing left element
// max node containing right element
// total node
// max node
node s_l, s_r, t, mx;
sub ( node _l, node _r, node _t, node _mx ){
s_l = _l;
s_r = _r;
t = _t;
mx = _mx;
}
sub(){}
};
sub DivideAndConquer(int* _myArray, int left, int right)
{
if(right == left){
node n (_myArray[left],right,left);
return sub( n, n, n, n);
}
int mid = (left+right)/2;
sub sub_left = DivideAndConquer( _myArray, left, mid);
sub sub_right = DivideAndConquer( _myArray, mid+1, right);
sub cur;
if ( sub_left.t.value + sub_right.s_l.value > sub_left.s_l.value ){
cur.s_l.value = sub_left.t.value + sub_right.s_l.value;
cur.s_l.r = sub_right.s_l.r;
cur.s_l.l = sub_left.s_l.l;
} else {
cur.s_l = sub_left.s_l;
}
if ( sub_right.t.value + sub_left.s_r.value > sub_right.s_r.value ){
cur.s_r.value = sub_right.t.value + sub_left.s_r.value;
cur.s_r.l = sub_left.s_r.l;
cur.s_r.r = sub_right.s_r.r;
} else {
cur.s_r = sub_right.s_r;
}
cur.t.value = sub_right.t.value + sub_left.t.value;
cur.t.r = sub_right.t.r;
cur.t.l = sub_left.t.l;
if ( cur.s_r.value >= cur.s_l.value &&
cur.s_r.value >= cur.t.value &&
cur.s_r.value >= sub_left.mx.value &&
cur.s_r.value >= sub_right.mx.value ){
cur.mx = cur.s_r;
} else if ( cur.s_l.value >= cur.s_r.value &&
cur.s_l.value >= cur.t.value &&
cur.s_l.value >= sub_left.mx.value &&
cur.s_l.value >= sub_right.mx.value ){
cur.mx = cur.s_l;
} else if ( sub_left.mx.value >= cur.s_l.value &&
sub_left.mx.value >= cur.t.value &&
sub_left.mx.value >= cur.s_r.value &&
sub_left.mx.value >= sub_right.mx.value ){
cur.mx = sub_left.mx;
} else {
cur.mx = sub_right.mx;
}
if ( sub_left.s_r.value + sub_right.s_l.value > cur.mx.value ){
cur.mx.value = sub_left.s_r.value + sub_right.s_l.value;
cur.mx.l = sub_left.s_r.l;
cur.mx.r = sub_right.s_l.r;
}
return cur;
}
int main()
{
// Example 1
//const int MyArraySize = 16;
//int MyArray[MyArraySize] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7 }; // answer: Index 7 -> 10, sum = 43
// Example 2
const int MyArraySize = 8;
int MyArray[MyArraySize] = { -2, -5, 6, -2, -3, 1, 5, -6 }; // answer: Index 2 -> 6, sum = 7
sub FinalResult = DivideAndConquer(MyArray, 0,MyArraySize-1);
std::cout << "Sum = " << FinalResult.mx.value << std::endl;
std::cout << "( " << FinalResult.mx.l << " , " << FinalResult.mx.r << ")" << std::endl;
// system("pause");
return 0;
}
注意:此算法在O(n)
时间内运行。
对于使用分治方法的最大和子数组算法,我需要返回和和子数组。 我能在所有的测试中正确地计算和。然而,我无法计算出正确的子数组。 我的总数(正确):34 阵列:2 9 8 6 5-11 9-11 7 5-1-8-3 7-2 正确子数组:2 9 8 6 5 我的总数(正确):50 阵列:31-41 59 26-53 58 97-93-23 84 正确子数组:59 26-53 58 97 我的总数(正确)
免责声明:我知道这个问题可以通过数组的单次传递非常有效地解决,但我对用分而治之法做这个很感兴趣,因为它与我们用分而治之法处理的典型问题有点不同。 假设给定一个浮点数组x[1:n],大小为n,间隔长度为l。问题是设计一个分治算法,从具有最大和的数组中找到长度为l的子数组。 现在,为了将问题分成两半,我决定在n-l+1/2处中断数组,以便将相等数量的子数组分配到我的除法的两半,如下面的算法所示。同样,
本文向大家介绍在C ++中使用分而治之算法的最大子数组总和,包括了在C ++中使用分而治之算法的最大子数组总和的使用技巧和注意事项,需要的朋友参考一下 假设我们有一个带有正值和负值的数据列表。我们必须找到其总和最大的连续子数组的总和。假设列表包含{-2,-5,6,-2,-3,1,5,-6},则最大子数组的总和为7。它是{6,-2,-3的总和,1,5} 我们将使用分而治之方法解决此问题。步骤如下所示
今年Spring我为一家IT公司写了实习入学考试。下面描述了一个问题。我不能解决它,所以我需要帮助(目前我要通过新的测试,所以我需要分析我的错误)。我很乐意为你效劳。 输入:一个数组arr,N个整数,arr的N个长度,数字K(K 对于offset的所有容许值,求s_arr(offset)的最小元素 算法复杂度应小于O(n*k) 输出:所有对(偏移量,最小(s_arr(偏移量)) 我的微不足道的解决
我在分而治之的算法上遇到了一点麻烦,正在寻找一些帮助。我试图编写一个名为sumArray的函数,它计算整数数组的和。 此函数必须通过将数组一分为二并对每一半执行递归调用来完成。我曾尝试使用类似的概念,当我编写递归和算法和分治算法来识别数组中的最大元素时,我使用了这些概念,但我很难将这两个想法结合起来。 下面是我为sumArray编写的代码,它编译,但没有返回正确的结果。