最大子列和 四种算法

问题描述:

给定N个整数的序列{A1,A2,A3,…An},求最大连续子列和

算法一

方法描述:暴力搜索,穷举 i 到 j 的所有可能子列和(0<= i <= j <= n),取其最大值。
时间复杂度:O(n^3)

C++实现

int MaxSubSum(int a[], int N){
	int thisMax = 0, maxSum = -1;
	for(int i = 0; i < N; i++){
		for(int j = i + 1; j < N; j++){
			thisMax = 0; 
			for(int k = i; k <= j; k++){
				thisMax += a[k];
			}
			if(thisMax > maxSum)
				maxSum = thisMax;
		}
	}
	return maxSum;
}

算法二

算法描述:暴力搜索。穷举时在thisSum计数基础上直接加上a[j],不必每次都从 i 加到 j 。
时间复杂度:O(n^2)

C++实现

int MaxSubSum(int a[], int N){
	int thisMax = 0, maxSum = -1;
	for(int i = 0; i < N; i++){
		thisMax = 0; 
		for(int j = i ; j < N; j++){
			thisMax += a[j];
			if(thisMax > maxSum)
				maxSum = thisMax;
		}
	}
	return maxSum;
}

算法三

算法描述:分治法。

  1. 将数列从中分成两个子数列,则最大子列有三种可能:在左边的数列中;在右边的数列中;一部分在左边数列,一部分在右边数列。
  2. 将左右两个子列不断二分,直至能直接判断当前数列的最大子列和,即子列元素个数小于等于 1 。如图:
    分治算法图解,取自浙大数据结构mooc
    时间复杂度:O(n * lg n)

Java实现

class Solution {
    public int maxSub(int[] nums, int s, int e){
        if(s >= e)
            return nums[e];
        int mid = (s+e)/2;
        int leftMax = nums[mid], rightMax = nums[mid+1];
        int leftSum = 0, rightSum = 0;
        for(int i = mid; i >= s; i--){
            leftSum += nums[i];
            leftMax = Math.max(leftMax, leftSum);
        }
        for(int i = mid+1; i <= e; i++){
            rightSum += nums[i];
            rightMax = Math.max(rightMax, rightSum);
        }
        leftMax = Math.max(0, leftMax);
        rightMax = Math.max(0, rightMax);

        int max = Math.max(maxSub(nums, s, mid), maxSub(nums, mid+1, e));
        if(max < 0)
            return max;
        return Math.max(max, leftMax+rightMax);
    }

	//调用
    public int maxSubArray(int[] nums) {
        return maxSub(nums, 0, nums.length-1);
    }
}

算法4

算法描述:在线处理。从数列第一个元素开始处理,依次向后求和,若发现当前所得的数列元素和为负,则舍弃之前所有元素,重新计数。
时间复杂度:O(n)

C++实现

int MaxSubSum(int a[], int N){
	int thisMax = 0, maxSum = -1;
	for(int i = 0; i < N; i++){
		thisMax += a[i];
		if(thisMax < 0)
			thisMax = 0;
		else if(thisMax > maxSum)
			maxSum = thisMax;
	}
	return maxSum;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值