题目描述:求出一个数组中连续子数组的和
eg:{6,-3,-2,7,-15,1,2,2} 所以最大连续字数组的和为(6,-3,-2,7 )为8。
method one:贪心算法
在使用贪心算法求解最大子数组问题之前,我们就要贪心,贪心的可以让连续的子数组越来越大,那么我们应该怎样贪心呢?
解析:首先我们想要得到数组中最大的连续子数组,那我们就得遍历整个数组,那么我们想要在遍历完数组后就可以得到最大值,所以我们就得尽可能多的在每一个元素遍历时留下最大的数据,从而为下次遇见大数据做好充足的准备。(即机会总是留给做准备的人(数据))
图解:
就如上图我们一直在使用count保留最多的能量,每次让count + arr[i] 和 arr[i] 相比较然后让较大的再赋值给count。
实现代码:c++
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
int max = array[0];
int count = array[0];
for (int i = 1; i < array.size(); i++)
{
if (count + array[i] > array[i])
{
count += array[i];
}
else
{
count = array[i];
}
if (count > max)
{
max = count;
}
}
return max;
}
};
int main()
{
int arr[] = { 6,-3,-2,7,-15,1,2,2 };
vector<int> brr(arr,arr+5);
Solution s;
cout << s.FindGreatestSumOfSubArray(brr) << endl;;
system("pause");
return 0;
}
method two:分治算法
首先给大家看一张图
解析:分治算法的核心就是把一个长的数组分成若干份,分别求出每段的字串的最大值,然后合并计算,比较求出合并后的最大子数组;
注意:每次合并一定要从两个合并区间的中间向两边进行遍历。
实现代码:c++
class Solution {
public:
int _max(vector<int> array, int start, int end)
{
if (start >= end)
{
return array[start];
}
int mid = (start + end) / 2;
int leftmax = _max(array, start, mid);
int rightmax = _max(array, mid + 1, end);
int leftsize = array[mid];
int left = 0;
int rightsize = array[mid + 1];
int right = 0;
int max = 0;
while (start <= mid)
{
left += array[mid];
if (left > leftsize)
{
leftsize = left;
}
mid--;
}
mid = (start + end) / 2 + 1;
while(mid <= end)
{
right += array[mid];
if (right > rightsize)
{
rightsize = right;
}
mid++;
}
max = leftsize + rightsize;
if (leftmax > max)
{
max = leftmax;
}
if (rightmax > max)
{
max = rightmax;
}
return max;
}
int FindGreatestSumOfSubArray(vector<int> array)
{
return _max(array, 0, array.size()-1);
}
};
int main()
{
int arr[] = { 6,-3,-2,7,-15,1,2,2 };
vector<int> brr(arr,arr+8);
Solution s;
cout << s.FindGreatestSumOfSubArray(brr) << endl;;
system("pause");
return 0;
}