JAVA算法:求连续子数组的最大和(详细讲解)

JAVA算法:求连续子数组的最大和(详细讲解)

给定一个一维整型数组,请这个数组中连续子数组的最大和。

这个题目很常见,可以参考我的另外两篇博文

https://blog.csdn.net/seagal890/article/details/88616329

https://blog.csdn.net/seagal890/article/details/89062176

这里说明一下 Kadane 算法(Kadane’s Algorithm)

伪代码如下:

Initialize:
    max_so_far = 0
    max_ending_here = 0

Loop for each element of the array
  (a) max_ending_here = max_ending_here + a[i]
  (b) if(max_ending_here < 0)
            max_ending_here = 0
  (c) if(max_so_far < max_ending_here)
            max_so_far = max_ending_here
return max_so_far

算法解释:

Kadane算法的简单思想是查找数组的所有正的连续段(这里使用max_ending_here)。并跟踪所有正段之间的最大和连续段(使用max_so_far)。每次我们得到一个正和,将它与max_so_far比较,如果它大于max_so_far,则更新max_so_far。

例如:给定数组 {-2, -3, 4, -1, -2, 1, 5, -3}

初始时,令:

    max_so_far = max_ending_here = 0

当 i=0时,a[0] =  -2
    max_ending_here = max_ending_here + (-2)

则:max_ending_here = 0 ,因为 max_ending_here < 0

当 i=1时,a[1] =  -3
    max_ending_here = max_ending_here + (-3)
则:max_ending_here = 0,因为 max_ending_here < 0

当 i=2时,a[2] =  4
    max_ending_here = max_ending_here + (4)
    max_ending_here = 4
则:max_so_far 更新为4,因为 max_ending_here =4  大于  max_so_far = 0
当 i=3时,a[3] =  -1
    max_ending_here = max_ending_here + (-1)
    max_ending_here = 3

当 i=4时,a[4] =  -2
    max_ending_here = max_ending_here + (-2)
    max_ending_here = 1

当 i=5时,a[5] =  1
    max_ending_here = max_ending_here + (1)
    max_ending_here = 2

当 i=6时,a[6] =  5
    max_ending_here = max_ending_here + (5)
    max_ending_here = 7
则:max_so_far 更新为 7,因为此时 max_ending_here 比 max_so_far 大

当 i=7时,a[7] =  -3
    max_ending_here = max_ending_here + (-3)
    max_ending_here = 4

则最终连续子数组的最大和为:7,这就是答案。

package com.bean.algorithm.basic;

public class MaxSumofCountinousSubarray {

	public static void main(String[] args) {
		int[] a = { -2, -3, 4, -1, -2, 1, 5, -3 };
		System.out.println("Maximum contiguous sum is " + maxSubArraySum(a));
	}

	static int maxSubArraySum(int a[]) {
		int size = a.length;
		int max_so_far = Integer.MIN_VALUE;
		int max_ending_here = 0;

		for (int i = 0; i < size; i++) {
			max_ending_here = max_ending_here + a[i];
			if (max_so_far < max_ending_here)
				max_so_far = max_ending_here;
			if (max_ending_here < 0)
				max_ending_here = 0;
		}
		return max_so_far;
	}

}

程序运行结果:

Maximum contiguous sum is 7

优化后的算法设计:

	static int maxSubArraySum(int a[]) {

		int max_so_far = 0;
		int max_ending_here = 0;

		int size = a.length;

		for (int i = 0; i < size; i++) {
			max_ending_here = max_ending_here + a[i];
			if (max_ending_here < 0)
				max_ending_here = 0;

			/*
			 * Compare only when max_ending_here > 0
			 */
			else if (max_so_far < max_ending_here)
				max_so_far = max_ending_here;

		}
		return max_so_far;
	}

程序运行结果:

Maximum contiguous sum is 7

下面的算法增加了列出最大连续子数组和的起始下标和结束下标:

package com.bean.algorithm.basic;

public class MaxSumofCountinousSubarray2 {

	static void maxSubArraySum(int a[], int size) {
		int max_so_far = Integer.MIN_VALUE, max_ending_here = 0, start = 0, end = 0, s = 0;

		for (int i = 0; i < size; i++) {
			max_ending_here += a[i];

			if (max_so_far < max_ending_here) {
				max_so_far = max_ending_here;
				start = s;
				end = i;
			}

			if (max_ending_here < 0) {
				max_ending_here = 0;
				s = i + 1;
			}
		}
		System.out.println("Maximum contiguous sum is " + max_so_far);
		System.out.println("Starting index " + start);
		System.out.println("Ending index " + end);
	}

	public static void main(String[] args) {
		int a[] = { -2, -3, 4, -1, -2, 1, 5, -3 };
		int n = a.length;
		maxSubArraySum(a, n);
	}

}

程序运行结果:

Maximum contiguous sum is 7
Starting index 2
Ending index 6

 

你可能感兴趣的:(算法分析与设计)