算法第三章上机实践报告
1.实践题目:7-2 最大子段和 (40 分)
2.问题题目:
给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。
要求算法的时间复杂度为O(n)。
输入格式:
输入有两行:
第一行是n值(1<=n<=10000);
第二行是n个整数。
输出格式:
输出最大子段和。
输入样例:
在这里给出一组输入。例如:
6
-2 11 -4 13 -5 -2
输出样例:
在这里给出相应的输出。例如:
20
3.算法描述:
1.定义memo[nums.length]数组,用来存放在各个位置的最大字段和,很明显memo[0]=nums[0],因为此处仅有nums[0]一个数字,故字段和为它。
2.进入一个循环(1,nums.length),要求得在i=1处的最大字段和,使memo[i]=(memo[i-1]>0?memo[i-1]+nums[i]:nums[i]),以此类推就可得出
memo数组,在遍历求其最大值即可。
4.参考代码:
import java.util.Scanner;
public class Main{
private static int[]memo;
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int[] nums=new int[n];
memo=new int[n];
for(int i=0;i<nums.length;i++){
nums[i]=input.nextInt();
}
System.out.println(solve(nums));
// for(int i:memo){
// System.out.println(i);
// }
}
private static int solve(int[] nums) {
int max=0;
memo[0]=nums[0];
for(int i=1;i<nums.length;i++){
if(memo[i-1]>0){
memo[i]=memo[i-1]+nums[i];
}else{
memo[i]=nums[i];
}
if(memo[i]>max){
max=memo[i];
}
}
return max;
}
}
5.复杂度分析
1.时间复杂度:一重循环,故为O(n)
2.空间复杂度:开了个大小和nums一样的memo数组,故为O(n)