【算法】求最大子序和 -- 动态规划

25 篇文章 1 订阅
  • 题目
    在这里插入图片描述
/**
 - @Author james
 - @Date 2019/7/19
 - @Description 求最大子序和 -- 动态规划
 */
public class Solution {
    public int maxSubArray(int[] nums) {
        if(nums.length == 0) {
            return 0;
        }

        /**
         *  修改int ans = 0;
         *  由边际条件:数组只有一个元素的时候,最大子序和就是该元素,而不是0
         */
        int ans = nums[0];

        /**
         *  sum -- 总增益值,判断是否重写统计增益的依据
         *  1. 如果 sum + [当前值] > [当前值] 证明 sum 的增益还是为正,可以继续添加子序
         *  2. 如果 sum + [当前值] <= [当前值] 证明 sum 之前的增益已经无用
         *      若原数组:[1, -2, 5, -3, -1, 9, 4, 6]
         *      遍历至:[1, -2, 5, -3, -1] 时,计算出sum = 0 => 增益为0,开始下一次遍历
         *      遍历至:[1, -2, 5, -3, -1, 9], 判断sum == 0 => 重置 sum = 9,意思是从9开始新的遍历才有意义
         *  3. ans 始终记录最大的sum,遍历完成返回即可
         */
        int sum = 0;
        for (int i = 0; i < nums.length; i++) {
            if (sum  > 0) {  // sum  + nums[i] > nums[i]
                sum = sum + nums[i];
            }
            if (sum <= 0) { // sum + nums[i] <= 0
                sum = nums[i];
            }
            ans = Math.max(ans, sum);
        }
        return ans;
    }
  • 类似题目
    在这里插入图片描述
/**
 * @Author james
 * @Date 2019/7/12
 * @Description 买卖股票最佳时机 (只允许一次买入和买出)
 */
public class Solution {
    public int maxProfit(int[] prices) {
	    /**
         *  只允许一次买入和买出,即在最低价买入,最高价卖出即可。
         *  若没有时间约束[6,4,2,1]
         *      => 最大利润为5 显然是不与合理的
         *      => 不能仅仅从价格高低定位最佳时间。
         *  于是可以【动态】得找到最大利润maxProfit = 当前值 - 最小值。
         *  并且,最小值的判断永远在计算利润之前,就不会发生[6,4,2,1]的错误答案
         */
        int maxProfit = 0;

        // 用于存放最小值,确保一定被数组的值覆盖,使用Integer的最大值最好
        int minVale = Integer.MAX_VALUE;

        for (int i = 0; i < prices.length; i++) {
            if (prices[i] < minVale) { // 找到最小值
                minVale = prices[i];
            }
            if (prices[i] - minVale > maxProfit) { // (当前值 - 最小值)比最大利润高,则记录下来
                maxProfit = prices[i] - minVale;
            }
        }
        return maxProfit;
    }
}
  • 通用思路
    1. 使用一个变量记录最值,遍历完整个数组,最值即确定。
    2. 使用循环遍历 + 前置判断,隐含了时间的约束条件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值