简单讲解最大连续子数组问题

题目描述:求出一个数组中连续子数组的和

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;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值