问题描述
给 定 一 个 整 数 数 组 num , 找 到 一 个 具 有 最 大 和 的 连 续 子 数 组 (子 数 组 最 少 包 含 一 个 元 素) , 返 回 其 最 大 和 。
示例:
输 入 : [ - 2 , 1 , - 3 , 4 , - 1 , 2 , 1 , - 5 , 4 ]
输 出: 6
解 释: 连 续 子 数 组 [4 , - 1 , 2 , 1 ] 的 和 最 大,为 6
动态规划解决
动 态 规 划 的 几 个 步 骤
1, 确 定 状 态
2, 找 到 转 移 公 式
3, 确 定 初 始 条 件 以 及 边 界 条 件
4, 计 算 结 果 。
1、
定 义 d p [ i ] 表 示 数 组 中 前 i+ 1 (注 意 这 里 的 i 是 从 0 开 始 的) 个 元 素 构 成 的 连 续 子 数 组 的 最 大 和 。
2、
如 果 要 计 算 前 i +1 个 元 素 构 成 的 连 续 子 数 组 的 最 大 和, 也 就 是 计 算 d p [ i ], 只 需 要 判 断 d p [ i - 1 ] 是 大 于 0 还 是 小 于 0 。 如 果 d p [ i - 1 ] 大 于 0, 就 继 续 累 加, d p [ i ] = d p [ i - 1 ] + n u m [ i ] 。 如 果 d p [ i - 1 ] 小 于 0, 我 们 直 接 把 前 面 的 舍 弃, 也 就 是 说 重 新 开 始 计 算, 否 则 会 越 加 越 小 的, 直 接 让 d p [ i ] = n u m [ i ] 。 所 以 转 移 公 式 如 下
d p [ i ] = n u m [ i ] + m a x ( d p [ i - 1 ] , 0 ) ;
3、边 界 条 件 判 断, 当 i 等 于 0 的 时 候, 也 就 是 前 1 个 元 素, 他 能 构 成 的 最 大 和 也 就 是 他 自 己, 所 以
d p [0 ] = n u m [0 ] ;
有了转 移 公 式, 代 码 就 简 单 多 了
代码
public class Array {
public static int maxSubArray(int[] num){
int length = num.length;
//边界条件
int cur = num[0];
int max = cur;
for(int i = 1;i<length;i++){
//转移公式
cur = Math.max(cur,0)+num[i];
//记录最大值
max = Math.max(max,cur);
}
return max;
}
public static void main(String[] args){
int[] array = {- 2 , 1 , - 3 , 4 , - 1 , 2 , 1 , - 5 , 4};
int max = maxSubArray(array);
System.out.println(max);
}
}
总结
动 态 规 划 最 重 要 的 3 步 就 是 先 确 定 状 态, 最 关 键 的 是 找 出 转 移 公 式, 最 后 再 确 定 边 界 条 件, 防 止 数 组 越 界 等 问 题