子数组最大累加和+子矩阵的最大和+子数组累加和为给定值的最大子数组长度

1.如何求一个子数组的最大累加和?(时间复杂度O(N))




class Solution
{
public:
	int SubArrayMaxSum(int *a, size_t n)
	{
		if ((a == NULL) || (n == 0))
			return 0;
		int max = a[0];
		int cur = 0;
		for (size_t i = 0; i < n; i++)
		{
			cur += a[i];
			max = (max>cur ? max : cur);  //当max > cur时,需要更新max
			if (cur < 0)
				cur = 0;                 //当cur < 0 时,需要将cur置0。
		}
		return max;
	}
};



2.如何求两个子数组的最大累加和?(要求两个子数组无重合的部分,时间复杂度O(N))






class Solution
{
public:
	int SubArrayMaxSum(int *a,  size_t n)
	{
		if ((a == NULL) || (n < 1))
			return 0;
		int maxR = a[n - 1];
		int curR = a[n - 1];
		vector<int> maxSubSumR;
		maxSubSumR.push_back(maxR);
		int maxSubSum = a[0];
		int cur = a[0];
		for (int i = n - 2; i >= 0; i--)
		{
			curR += a[i];
			maxR = (maxR > curR ? maxR : curR);  //当max > cur时,需要更新max
			maxSubSumR.push_back(maxR);
			if (curR < 0)
				curR = 0;                 //当cur < 0 时,需要将cur置0。
		}
		int max = a[0] + maxSubSumR[n - 2];
		int j = 1;
		for (int i = n - 3; i >= 0; i--)
		{
			cur += a[j];
			maxSubSum = (maxSubSum>cur ? maxSubSum : cur);
			max = (max > (maxSubSum + maxSubSumR[i]) ? max : (maxSubSum + maxSubSumR[i]));
			j++;
			if (cur < 0)
				cur = 0;
		}
		return max;
	}
};

3.未排序的正数数组中累加和为给定值的最长子数组长度(时间复杂度O(N))



class   Solution 
{
public:
	int SubArrayMaxLegth(int* a, int n, int key)
	{
		if (a == NULL || n < 0 || key < 0)
			return -1;
		int left = -1;
		int length = 0;
		int maxLength = 0;
		int  right = -1;
		int sum = 0;
		//循环结束的条件left==right&& left==n-1||right > n-1
		while ((left != right) || (left != n - 1))
		{
			if (sum > key)
			{
				left++;
				sum -= a[left];
				length--;
			}
			else
			{
				if (sum == key)
				{
					maxLength = maxLength > length ? maxLength : length;
				}
					right++;
					length++;
					if (right > n - 1)
						break;
					sum += a[right];
			}
		}
		return maxLength;
	}
};

4.子矩阵的最大和问题求解


#define  M 100
#define  N 100
class Solution
{
public:
	int SubMatrixMax(int a[4][4], int m, int n)
	{
		if (a == NULL)
			return 0;
		int SubMatrixValue[M][N] = { 0 };//SubMatrixValue数组的大小可以根据m*n二维数组的大小来确定
		for (int i = 0; i < m; i++)
		{
			for (int j = 0; j < n; j++)
			{
				if (i == 0)
					SubMatrixValue[i][j] = a[i][j];
				else
					SubMatrixValue[i][j] = SubMatrixValue[i - 1][j] + a[i][j];
			}
		}
		//求出了1——>m行每一列的子数组中每一列的和
		int max = SubMatrixValue[0][0];
		int cur = SubMatrixValue[0][0];
		for (int k = -1; k < m; k++)
		{
		
			for (int i = k + 1; i < m; i++)
			{
				if (k != -1)
				{
					for (int j = 0; j < n; j++)
					{
						SubMatrixValue[i][j] -= SubMatrixValue[k][j];
					}
				}
				cur = SubMatrixValue[i][0];
				for (int j = 0; j < n; j++)
				{
					if (i != 0)
						cur += SubMatrixValue[i][j];
					else
						cur = SubMatrixValue[i][0];
					if (cur > max)
						max = cur;
					if (cur < 0)
						cur = 0;
				}
			}
		}
		return max;
	}
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值