求最大连续和的几种方法

本文介绍了三种不同的算法方法来解决寻找序列中最大连续和的问题。方法一采用暴力枚举,时间复杂度为O(n^3);方法二利用前缀和优化至O(n^2);方法三通过分治法实现O(n log n)的时间复杂度。这些方法在解决此类问题时提供了效率上的选择。
摘要由CSDN通过智能技术生成

本文内容参考《算法竞赛入门经典第2版》220~223页
Q:给出一个长度为 n n n的序列 A 1 , A 2 , A 3 , ⋯   , A n A_{1},A_{2},A_{3},\cdots,A_{n} A1,A2,A3,,An,求最大连续和。换句话说,要求找到 1 ≤ i ≤ j ≤ n 1\leq i\leq j \leq n 1ijn,使得 A i + A i + 1 + ⋯ + A j A_{i}+A_{i+1}+\cdots+A_{j} Ai+Ai+1++Aj尽量大。
方法一:
暴力枚举,时间复杂度 O ( n 3 ) O(n^{3}) O(n3)

ans=A[1];//所求的最大连续和 
for(int i=1;i<=n;i++){
	for(int j=i;j<=n;j++){//枚举区间[i,j] 
		int sum=0;
		for(int k=i;k<=j;k++){//对区间[i,j]内的所有数求和 
			sum+=A[k];
		}
		ans=max(sum,ans);//取最大值 
	}
}

方法二:
利用前缀和,时间复杂度 O ( n 2 ) O(n^{2}) O(n2)

s[0]=0;
for(int i=1;i<=n;i++){//提前求前缀和(s[i]表示从A[i]数组从1到i的所有数之和),降低时间复杂度 
	s[i]=s[i-1]+A[i];
}
ans=s[0];
for(int i=1;i<=n;i++){
	for(int j=i;j<=n;j++){
		ans=max(ans,s[j]-s[i-1]);
	}
}

方法三:
分治法,时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)

int maxSum(int*A,int x,int y){//返回数组在左闭右开区间[x,y)中的最大连续和 
	if(y-x==1){
		return A[x];
	}
	int m=x+(y-x)/2;//划分成[x,m)和[m,y) 
	int maxs=max(maxSum(A,x,m),maxSum(A,m,y));
	int v,L,R;
	v=0;
	L=A[m-1];
	for(int i=m-1;i>=x;i--){//从分界点往左的最大连续和 
		L=max(L,v+=A[i]);
	}
	v=0;
	R=A[m];
	for(int i=m;i<y;i++){//从分界点往右的最大连续和 
		R=max(R,v+=A[i]);
	}
	return max(maxs,L+R);//子问题的解与L和R比较 
} 
好的,关于连续字符最大和的问题,下面我为您介绍几种 C++ 的实现方法: 1. 前缀和:使用前缀和可以将时间复杂度从 O(n^2) 优化到 O(n)。具体实现可以参考下面的代码: ```c++ int maxSubArray(vector<int>& nums) { int n = nums.size(); vector<int> preSum(n + 1); int ans = nums[0]; for (int i = 1; i <= n; i++) { preSum[i] = preSum[i - 1] + nums[i - 1]; } int minPre = preSum[0]; for (int i = 1; i <= n; i++) { ans = max(ans, preSum[i] - minPre); minPre = min(minPre, preSum[i]); } return ans; } ``` 2. 动态规划:使用动态规划也可以解决这个问题。具体实现可以参考下面的代码: ```c++ int maxSubArray(vector<int>& nums) { int n = nums.size(); vector<int> dp(n); dp[0] = nums[0]; int ans = dp[0]; for (int i = 1; i < n; i++) { dp[i] = max(dp[i - 1] + nums[i], nums[i]); ans = max(ans, dp[i]); } return ans; } ``` 3. 分治法:使用分治法也可以解决这个问题。具体实现可以参考下面的代码: ```c++ int maxSubArray(vector<int>& nums) { int n = nums.size(); if (n == 1) { return nums[0]; } int mid = n / 2; vector<int> left(nums.begin(), nums.begin() + mid); vector<int> right(nums.begin() + mid, nums.end()); int leftMax = maxSubArray(left); int rightMax = maxSubArray(right); int crossMax = nums[mid - 1] + nums[mid]; int crossSum = crossMax; for (int i = mid - 2; i >= 0; i--) { crossSum += nums[i]; crossMax = max(crossMax, crossSum); } crossSum = crossMax; for (int i = mid; i < n; i++) { crossSum += nums[i]; crossMax = max(crossMax, crossSum); } return max(leftMax, max(rightMax, crossMax)); } ``` 以上就是几种 C++ 实现连续字符最大和的方法,希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值