最大连续子数组和

输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。

求所有子数组的和的最大值,要求时间复杂度为O(n)。

#define SIZE 8
#define COLUMN 4

void MaxSumSubArray(int* arr) {
	int curSum = 0;
	int maxSum = arr[0];
	int maxBegin = 0;
	int maxEnd = 0;
	int tmpBegin = 0;
	//找出最大值
	for (int i = 0; i < SIZE; ++i) {
		curSum = curSum + arr[i] > arr[i] ? curSum + arr[i] : arr[i];
		if (curSum == arr[i]) {
			tmpBegin = i;
		}
		maxSum = curSum > maxSum ? curSum : maxSum;
		if (curSum == maxSum) {
			if (tmpBegin != maxBegin) {
				maxBegin = tmpBegin;
			}
			maxEnd = i;
		}
	}

	cout << "maxBegin:" << maxBegin << ", maxEnd:" << maxEnd << endl;
	cout << "MaxSubArray:" << endl;
	for (int i = maxBegin; i <= maxEnd; ++i) {
		cout << " " << arr[i];
	}
	cout << endl << "maxSum:" << maxSum << endl;
}


### 实现最大连续子数组算法 在前端开发中,使用JavaScript实现最大连续子数组算法是非常常见的任务。该问题通常可以通过**Kadane算法**高效解决。Kadane算法是一种动态规划算法,其核心思想是通过遍历数组一次,计算以当前元素结尾的最大子数组,并最终找到全局最大值。 #### Kadane 算法实现 以下是一个使用 Kadane 算法的实现示例: ```javascript function maxSubArraySum(arr) { let maxCurrent = arr[0]; let maxGlobal = arr[0]; for (let i = 1; i < arr.length; i++) { maxCurrent = Math.max(arr[i], maxCurrent + arr[i]); maxGlobal = Math.max(maxGlobal, maxCurrent); } return maxGlobal; } console.log(maxSubArraySum([-2, 1, -3, 4, -1, 2, 1, -5, 4])); // 输出: 6 ``` 在这个实现中: - `maxCurrent` 表示以当前元素结尾的最大子数组。 - `maxGlobal` 表示整个数组中最大子数组。 - 每次迭代时,`maxCurrent` 的值是 `arr[i]` `maxCurrent + arr[i]` 中的较大者。 - 最终,`maxGlobal` 会保存全局最大值[^1]。 #### 暴力解法 尽管暴力解法的时间复杂度较高(O(n&sup2;)),但仍然可以用来解决问题。以下是暴力解法的实现: ```javascript function maxSubArraySumBruteForce(arr) { let maxSum = Number.MIN_SAFE_INTEGER; for (let i = 0; i < arr.length; i++) { let sum = 0; for (let j = i; j < arr.length; j++) { sum += arr[j]; maxSum = Math.max(maxSum, sum); } } return maxSum; } console.log(maxSubArraySumBruteForce([-2, 1, -3, 4, -1, 2, 1, -5, 4])); // 输出: 6 ``` 暴力解法通过双重循环遍历所有可能的子数组,并计算它们的,最终找到最大值[^1]。 #### 分治法实现 分治法是一种更高级的算法思想,它将数组分成两部分,并分别计算左半部分、右半部分跨越中间的最大子数组,最终比较三者的最大值。以下是分治法的实现思路: ```javascript function maxSubArraySumDivideAndConquer(arr) { function maxCrossingSum(arr, left, mid, right) { let sum = 0; let leftSum = Number.MIN_SAFE_INTEGER; for (let i = mid; i >= left; i--) { sum += arr[i]; leftSum = Math.max(leftSum, sum); } sum = 0; let rightSum = Number.MIN_SAFE_INTEGER; for (let i = mid + 1; i <= right; i++) { sum += arr[i]; rightSum = Math.max(rightSum, sum); } return leftSum + rightSum; } function maxSubArraySumUtil(arr, left, right) { if (left === right) { return arr[left]; } const mid = Math.floor((left + right) / 2); return Math.max( maxSubArraySumUtil(arr, left, mid), maxSubArraySumUtil(arr, mid + 1, right), maxCrossingSum(arr, left, mid, right) ); } return maxSubArraySumUtil(arr, 0, arr.length - 1); } console.log(maxSubArraySumDivideAndConquer([-2, 1, -3, 4, -1, 2, 1, -5, 4])); // 输出: 6 ``` 分治法通过递归将数组拆分,并计算左半部分、右半部分跨越中间部分的最大子数组,最终找到全局最大值[^4]。 #### 时间复杂度对比 - **Kadane 算法**:时间复杂度为 O(n),空间复杂度为 O(1)。 - **暴力解法**:时间复杂度为 O(n&sup2;),空间复杂度为 O(1)。 - **分治法**:时间复杂度为 O(n log n),空间复杂度为 O(log n)(递归栈)。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值