求解最大子列和

求解数列的最大子列和问题,显然我们可以穷举所有长度的子列然后一一比较大小来求得。但空间复杂度太大为n3。现在我们来学习一种新的解决方法。

我们以一个任意子列为例子:0,-2,6,1,-4,3,-12,17,-6;相比较于穷举比较,这个方法只需要遍历一遍。

第一步:0,对后续子列大小无影响,存入,不保留。(此处考虑当子列最短时的最大值)

第二步:-2,对后续子列减小,与上一次存入0比较,小于0,不存入,不保留。

第三步:6,对后续子列增大,与上一次存入0比较,大于0,存入6,保留6并暂定为最大子列起点。

第四步:1,对后续子列增大,与上一次存入6比较,(此处为累加为7)大于6,保留7存入7。

第五步:-4,对后续子列减小,与上一次存入7比较,(此处为累加为3)小于7,保留3但不存入。

第六步:3,对后续子列增大,与上一次存入7比较,(此处为累加为6)小于7,保留6但不存入。

第七步:-12.对后续子列减小,与上一次存入7比较,(此处为累加为-6)小于7,小于0,不保留不存入。

第八步:17 对后续子列增大,与上一次存入7比较,(因为第七步累加结果小于0了,未保留所以这一步并没有累加)大于7,保留并存入且更新最大子列起点。

第九步:-6 对后续子列减小,与上一次存入17比较,(此处累加为11)小于17,保留但不存入。

到这里,整个数列已经遍历一边且得出了最大子列和为17。

#include <stdio.h>  

int maxSubArraySum(int arr[], int n) {  
    int max_so_far = arr[0];  
    int max_ending_here = arr[0];  

    for (int i = 1; i < n; i++) {  
        max_ending_here = (max_ending_here > 0) ? max_ending_here + arr[i] : arr[i];  
        if (max_ending_here > max_so_far) {  
            max_so_far = max_ending_here;  
        }  
    }  
    
    return max_so_far;  
}  

int main() {  
    int n;  

    printf("请输入数列的长度: ");  
    scanf("%d", &n);  

    int arr[n]; // 动态分配数组  

    printf("请输入数列的元素 (用空格分隔): ");  
    for (int i = 0; i < n; i++) {  
        scanf("%d", &arr[i]);  
    }  

    int max_sum = maxSubArraySum(arr, n);  
    printf("最大子列和为: %d\n", max_sum);  

    return 0;  
}
import java.util.Scanner;  

public class MaxSubArraySum {  
    
    public static int maxSubArraySum(int[] arr) {  
        int maxSoFar = arr[0];  // 初始化最大子列和  
        int maxEndingHere = arr[0];  // 以当前元素结尾的子列和  
        
        for (int i = 1; i < arr.length; i++) {  
            // 计算到当前元素的最大子列和  
            maxEndingHere = Math.max(arr[i], maxEndingHere + arr[i]);  
            // 更新全局最大值  
            maxSoFar = Math.max(maxSoFar, maxEndingHere);  
        }  
        
        return maxSoFar;  
    }  

    public static void main(String[] args) {  
        Scanner scanner = new Scanner(System.in);  

        System.out.print("请输入数列的长度: ");  
        int n = scanner.nextInt();  

        int[] arr = new int[n];  
        System.out.println("请输入数列的元素 (用空格分隔): ");  
        for (int i = 0; i < n; i++) {  
            arr[i] = scanner.nextInt();  
        }  

        int maxSum = maxSubArraySum(arr);  
        System.out.println("最大子列和为: " + maxSum);  

        scanner.close();  
    }  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值