求最大子数组02

题目:整数数组中最大子数组的和

要求:

  1. 输入一个整形数组,数组里有正数也有负数。
  2. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
  3. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1],…… A[n-1],A[0]……A[j-1]之和最大。
  4. 同时返回最大子数组的位置。 求所有子数组的和的最大值。  

这次要求数组是环形的 高逸凡同学上课的思路很清晰,在此基础上我也没有什莫更好的思路了,就是锁定节点确定子数组就好。子数组的长度一定小于等于原数组,那么两个数组Arr首尾相接构成的新数组肯定可以包含所有子数组,

然后再打表求所有子数组的和,再求max。

1 #include <iostream>
 2 #include <vector>
 3 using namespace std;
 4 #define max_Num 100
 5 int main(int argc, char *argv[])
 6 {
 7     int a[]={115,15,-565,9465,-66,11,15,9400};
 8     vector<int> arr(a,a+(int)(sizeof(a)/sizeof(int)));
 9     arr.insert(arr.end(),arr.begin(),arr.end());
10     int arrtemp[max_Num][max_Num]={0};         //记录数列之和的表  arrtemp[i][j]表示为子数组arr中[i,j]元素之和
11     for(int i = 0;i <(int)(arr.size()/2); i++)
12     {
13         for(int j = 0;j<(int)(arr.size());j++)
14         {
15             if((i <= j) && (j < i + (int)(arr.size()/2)))  //i<=j控制元素顺序,j <i+length控制子数列长度
16             {
17                 for(int k = i; k <= j; k++)
18                 {
19                     arrtemp[i][j] += arr[k];
20                 }
21             }
22         }
23     }
24 
25     int maxtemp = arrtemp[0][0];   //临时最大值设为arr[0][0]即 arr[0]
26     int start = 0;
27     int end = 0;
28     for(int i = 0;i < (int)(arr.size()/2); i++)
29     {
30         for(int j = 0;j < (int)(arr.size());j++)
31         {
32             if((i <= j) && (j < (int)(i+arr.size()/2)))  //i<=j控制元素顺序,j<i+length控制子数列长度
33             {
34                 if( arrtemp[i][j] > maxtemp)
35                 {
36                     maxtemp = arrtemp[i][j];
37                     start = i;
38                     end = j;
39                 }
40             }
41         }
42     }
43 
44     cout <<"sum:"<< maxtemp <<"start:"<< start <<"end:"<<end % (arr.size() / 2) <<endl;
45     return 0;
46 }

(i <= j) && (j < (int)(i+arr.size()/2))是控制元素求和用的,比如一个数组有4个元素,那么求和打表的内容只能填充到
O O O O X X X X
X O O O O X X X
X X O O O O X X
X X X O O O O X
中 O 的位置,其他位置不可能是子数组之和。

这个程序的复杂度是O(n2) 。

缺陷记录日志

日期编号类型引入阶段排除阶段修复时间修复缺陷
3/271stack overflow编码调试20min 




转载于:https://www.cnblogs.com/liuwei8882/p/5350104.html

内容概要:本文深入探讨了金属氢化物(MH)储氢系统在燃料电池汽车中的应用,通过建立吸收/释放氢气的动态模型和热交换模型,结合实验测试分析了不同反应条件下的性能表现。研究表明,低温环境有利于氢气吸收,高温则促进氢气释放;提高氢气流速和降低储氢材料体积分数能提升系统效率。论文还详细介绍了换热系统结构、动态性能数学模型、吸放氢特性仿真分析、热交换系统优化设计、系统控制策略优化以及工程验证与误差分析。此外,通过三维动态建模、换热结构对比分析、系统级性能优化等手段,进一步验证了金属氢化物储氢系统的关键性能特征,并提出了具体的优化设计方案。 适用人群:从事氢能技术研发的科研人员、工程师及相关领域的研究生。 使用场景及目标:①为储氢罐热管理设计提供理论依据;②推动车载储氢技术的发展;③为金属氢化物储氢系统的工程应用提供量化依据;④优化储氢系统的操作参数和结构设计。 其他说明:该研究不仅通过建模仿真全面验证了论文实验结论,还提出了具体的操作参数优化建议,如吸氢阶段维持25-30°C,氢气流速0.012g/s;放氢阶段快速升温至70-75°C,水速18-20g/min。同时,文章还强调了安全考虑,如最高工作压力限制在5bar以下,温度传感器冗余设计等。未来的研究方向包括多尺度建模、新型换热结构和智能控制等方面。
### 最大子数组和算法的实现 最大子数组和问题的目标是找到一个数组中和最大的连续子数组。该问题在算法领域中具有重要意义,尤其在动态规划和分治算法的应用中被广泛研究。 #### 方法1:蛮力法 蛮力法是最直观的解决方案,其基本思想是遍历所有可能的子数组,计算它们的和,并从中找出最大值。这种方法的时间复杂度为 $O(n^2)$,对于较小的数组规模是可行的,但对于较大的数组则效率较低。 以下是C语言实现: ```c #include <stdio.h> int maxSubArray1(int a[], int n) { int maxSum = 0; int i, j; for (i = 0; i < n; i++) { int currentSum = 0; for (j = i; j < n; j++) { currentSum += a[j]; if (currentSum > maxSum) { maxSum = currentSum; } } } return maxSum; } int main() { int arr[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; int n = sizeof(arr) / sizeof(arr[0]); printf("最大子数组的和为: %d\n", maxSubArray1(arr, n)); return 0; } ``` #### 方法2:动态规划法 动态规划法是解决最大子数组和问题的经典方法,其时间复杂度为 $O(n)$,效率显著优于蛮力法。其核心思想是维护一个当前子数组的和,如果当前子数组的和小于0,则丢弃之前的子数组并重新开始计算。 以下是C语言实现: ```c #include <stdio.h> int maxSubArray2(int a[], int n) { int maxSum = a[0]; int currentSum = a[0]; for (int i = 1; i < n; i++) { currentSum = (currentSum + a[i] > a[i]) ? currentSum + a[i] : a[i]; maxSum = (currentSum > maxSum) ? currentSum : maxSum; } return maxSum; } int main() { int arr[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; int n = sizeof(arr) / sizeof(arr[0]); printf("最大子数组的和为: %d\n", maxSubArray2(arr, n)); return 0; } ``` #### 方法3:分治法 分治法将数组分为左右两部分,分别解左半部分和右半部分的最大子数组和,同时考虑跨越中间的最大子数组和。这种方法的时间复杂度为 $O(n \log n)$,适合大规模数据的处理。 以下是C语言实现: ```c #include <stdio.h> // 三者中的最大值 int max(int a, int b, int c) { return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c); } // 跨越中间的最大子数组和 int maxCrossingSum(int a[], int left, int mid, int right) { int sum = 0; int leftSum = -999999; for (int i = mid; i >= left; i--) { sum += a[i]; if (sum > leftSum) { leftSum = sum; } } sum = 0; int rightSum = -999999; for (int i = mid + 1; i <= right; i++) { sum += a[i]; if (sum > rightSum) { rightSum = sum; } } return leftSum + rightSum; } // 分治法主函数 int maxSubArray3(int a[], int left, int right) { if (left == right) { return a[left]; } int mid = (left + right) / 2; int leftMax = maxSubArray3(a, left, mid); int rightMax = maxSubArray3(a, mid + 1, right); int crossMax = maxCrossingSum(a, left, mid, right); return max(leftMax, rightMax, crossMax); } int main() { int arr[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; int n = sizeof(arr) / sizeof(arr[0]); printf("最大子数组的和为: %d\n", maxSubArray3(arr, 0, n - 1)); return 0; } ``` ### 总结 - **蛮力法**:简单直观,但效率较低,时间复杂度为 $O(n^2)$。 - **动态规划法**:高效且简洁,时间复杂度为 $O(n)$。 - **分治法**:适用于大规模数据,时间复杂度为 $O(n \log n)$,但实现较复杂。 根据具体需和数据规模,可以选择合适的算法实现最大子数组和的解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值