最大子数组问题求解
问题描述
一个数组中包含的元素有正有负,在该数组中寻找出一个连续非空子数组,要求该连续子数组的和最大,这就是最大子数组问题。
比如 nums = [4,3,-1,2,-2,-3,1],那么最大子数组就是[4,3,-1,2],和为4+3-1+2 = 8.
思路
利用分治法求解最大子数组问题。假定我们需要寻找数组nums[low,high]的最大子数组,使用分治法意味着我们要将子数组划分为两个规模尽量相等的子数组,也就是说,找到数组中央的位置,比如mid,然后考虑求解nums[low,mid]和nums[mid+1,high],nums的子数组只有如下三种情况:
1.完全位于子数组A[low,mid]中;
2.完全位于A[mid+1,high]中;
3.跨越了中点。
C++代码如下
#include <iostream>
using namespace std;
struct sumBorder{
int left;
int right;
int summax;
};
sumBorder get_maxSubarraycrossmid(int *nums, int low, int high, int mid);
sumBorder get_maxsumary(int *nums, int low, int high);
int main()
{
int *nums = new int[8];
sumBorder rst;
for (int i = 0; i < 8; i++){
*(nums + i) = i - 5;
cout << *(nums + i) << endl;
}
cout << "我是分隔符O(∩_∩)O~"<<endl;
rst = get_maxsumary(nums, 0, 7);
cout << rst.left << endl;
cout << rst.right << endl;
cout << rst.summax << endl;
system("pause");
return 0;
}
sumBorder get_maxSubarraycrossmid(int *nums, int low, int high, int mid)
{
int max_sumleft = 0;
int sum_left = 0;
int left_order = 0;
sumBorder ret;
for (int i = mid; i >=low; i--)
{
sum_left += nums[i];
if (sum_left > max_sumleft)
{
max_sumleft = sum_left;
left_order = i;
}
}
int max_sumright = 0;
int sum_right = 0;
int right_order = 0;
for (int i = mid + 1; i <= high; i++)
{
sum_right += nums[i];
if (sum_right > max_sumright)
{
max_sumright = sum_right;
right_order = i;
}
}
ret.left = left_order;
ret.right = right_order;
ret.summax = max_sumleft + max_sumright;
return ret;
}
sumBorder get_maxsumary(int *nums, int low, int high)
{
/*int *p1 = new int[8];*/
sumBorder rut,rut_left,rut_right,rut_cross;
if (low == high)
{
rut.left = low;
rut.right = high;
rut.summax = nums[low];
return rut;
}
else{
int mid = (low + high) / 2;
rut_left = get_maxsumary(nums, low, mid);
rut_right = get_maxsumary(nums, mid + 1, high);
rut_cross = get_maxSubarraycrossmid(nums, low, high, mid);
}
if ((rut_left.summax >= rut_right.summax)&&(rut_left.summax>=rut_cross.summax)){
return rut_left;
}
else if ((rut_right.summax >= rut_left.summax) && (rut_right.summax >= rut_cross.summax)){
return rut_right;
}
else
{
return rut_cross;
}
}
总结
楼主属于算法小白,最近才开始把一些经典的算法由“懂的”转化为可以写出来,代码都是亲测通过的,希望大神指出楼主考虑不全的地方。
C++返回多个值用结构体很方便,前一段写一个网络帧分析的软件,返回指针总是出现莫名其妙的值,改成结构体稳定多了,还是指针没学明白啊。