LeetCode-53. Maximum Subarray( 最大子序和)(一维dp)

LeetCode-53. Maximum Subarray( 最大子序和)(一维dp)

  • 递归写法
  • 一维dp数组
  • 滚动优化

递归写法

递归和动态规划永远是可以转换的,我们可以从数组的最后开始往前看,对于当前数nums[i],以这个nums[i]结尾的最大值一定是你前面的所有数求出一个最大的子序和(但是由于是子数组,所以必须是判断前一个数)+我自己(nums[i]),所以这是一个递归的过程,边界条件就是i = 0时,最大子序和就是自己。

    public int max;
    public int maxSubArray(int[] nums){
        max = nums[0];
        process(nums,nums.length-1);
        return max;
    }
    public int process(int[] nums,int index){
        if(index == 0){
            return nums[0];
        }else {
            int pre = process(nums,index-1);  //先给我求出前面的最大子序和
            int cur = pre > 0 ? pre + nums[index] : nums[index];
            max = Math.max(cur,max);
            return cur;
        }
    }

一维dp数组

动态规划就是从小问题到大问题,递归相反的方向,我们可以正向的保存一个以每一个数结尾的最大子序和的数组,然后递推到最后一个,其中使用个max保存最大值;
这里写图片描述

   public int maxSubArray(int[] nums) {
        int[] ends = new int[nums.length];
        ends[0] = nums[0];
        int max = ends[0];
        for(int i = 1; i < nums.length; i++){
             ends[i] = ends[i-1] > 0 ? ends[i-1] + nums[i] : nums[i];
             max = Math.max(max,ends[i]);
        }
        return max;
    }

滚动优化

类似二维dp的滚动数组优化,因为每个位置只需要它前面的一个位置,所以我们只需要用一个变量保存即可。

    public int maxSubArray(int[] nums) {
        int preMax = nums[0];
        int max = nums[0];
        for(int i = 1; i < nums.length; i++){
            preMax = preMax > 0 ? preMax + nums[i]: nums[i];
            max = Math.max(max,preMax);
        }
        return max;
    }

猜你喜欢

转载自blog.csdn.net/zxzxzx0119/article/details/81807083