连续子数组的最大和(二)
https://www.nowcoder.com/practice/11662ff51a714bbd8de809a89c481e21
import java.util.*;
/**
* NC166 连续子数组的最大和(二)
* @author d3y1
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param array int整型一维数组
* @return int整型一维数组
*/
public int[] FindGreatestSumOfSubArray (int[] array) {
// return solution1(array);
return solution2(array);
// return solution3(array);
}
/**
* 前缀和 + 滑动窗口
*
* 超时!
*
* @param array
* @return
*/
private int[] solution1(int[] array){
int len = array.length;
int[] dp = new int[len+1];
for(int i=1; i<=len; i++){
dp[i] = dp[i-1] + array[i-1];
}
int max = Integer.MIN_VALUE;
int left=0,right=len,sum;
for(int gap=len; gap>0; gap--){
for(int j=0; j+gap<=len; j++){
sum = dp[j+gap] - dp[j];
if(sum > max){
max = sum;
left = j;
right = j+gap;
}
}
}
int[] result = new int[right-left];
for(int i=0,j=left; j<right; i++,j++){
result[i] = array[j];
}
return result;
}
/**
* 动态规划
*
* dp[i]表示以数组中第i个整数为结尾(必选)的最大和
*
* { dp[i-1] + array[i-1] , dp[i-1] >= 0
* dp[i] = {
* { array[i-1] , dp[i-1] < 0
*
* @param array
* @return
*/
private int[] solution2(int[] array){
int len = array.length;
int[] dp = new int[len+1];
int index=1,width = 0;
int maxSum = Integer.MIN_VALUE;
int lastWidth = Integer.MIN_VALUE;
for(int i=1; i<=len; i++){
if(dp[i-1] >= 0){
dp[i] = dp[i-1] + array[i-1];
width++;
}else{
dp[i] = array[i-1];
width = 1;
}
// 最大和更大
if(dp[i] > maxSum){
maxSum = dp[i];
index = i;
lastWidth = width;
}
// 最大和相同 且 长度更长
else if(dp[i]==maxSum && width>lastWidth){
index = i;
lastWidth = width;
}
}
int[] result = new int[lastWidth];
for(int i=0,j=index-lastWidth; j<index; i++,j++){
result[i] = array[j];
}
return result;
}
/**
* 动态规划: 空间压缩
*
* pre 表示以数组中上一整数为结尾的最大和
* curr表示以数组中当前整数为结尾的最大和
*
* { pre + array[i-1] , pre >= 0
* curr = {
* { array[i-1] , pre < 0
*
* @param array
* @return
*/
private int[] solution3(int[] array){
int len = array.length;
int index=1,width = 0;
int maxSum = Integer.MIN_VALUE;
int lastWidth = Integer.MIN_VALUE;
int pre=0,curr;
for(int i=1; i<=len; i++){
if(pre >= 0){
curr = pre + array[i-1];
width++;
}else{
curr = array[i-1];
width = 1;
}
// 最大和更大
if(curr > maxSum){
maxSum = curr;
index = i;
lastWidth = width;
}
// 最大和相同 且 长度更长
else if(curr==maxSum && width>lastWidth){
index = i;
lastWidth = width;
}
pre = curr;
}
int[] result = new int[lastWidth];
for(int i=0,j=index-lastWidth; j<index; i++,j++){
result[i] = array[j];
}
return result;
}
}