给定一个一维整型数组,请这个数组中连续子数组的最大和。
这个题目很常见,可以参考我的另外两篇博文
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