LeetCode01 Maximum Sum of Contiguous Subarrays (Dynamic Programming)

Maximum sum of consecutive subarrays

Enter an integer array. One or more consecutive integers in the array form a sub-array. Find the maximum value of the sum of all sub-arrays.

The required time complexity is O(n).

Example 1:

Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: The sum of consecutive sub-arrays [4,-1,2,1] is the largest, which is 6.

prompt:

1 <= arr.length <= 10^5
-100 <= arr[i] <= 100

Dynamic programming analysis:

​ General idea: Define a dynamic programming array dp with the same size as the target array num. After traversal, the value of dp[i] is the maximum sum of continuous sub-arrays ending with element num[i]. The implementation principle is as follows

State definition:

1. Let the dynamic programming list dp, dp[i] represent the maximum sum of consecutive sub-arrays ending with element nums[i] .

​ Why define the maximum sum dp[i] must contain the element nums[i]: to ensure the correctness of dp[i] recursively to dp[i + 1];

​ If nums[i] is not included, the continuous sub-array requirement of the question will not be met during recursion.

2. Transfer equation: If dp[i-1]≤0, it means that dp[i-1] has a negative contribution to dp[i], that is, dp[i-1] + nums[i] is not as good as nums[i] itself Big.

​ When dp[i-1]> 0: execute dp[i] = dp[i- 1] + nums[i];

​ When dp[i -1]≤0: execute dp[i]= nums[i];

3. Initial state:

​ dp[0] = nums[0], that is, the maximum sum of consecutive sub-arrays ending in nums[0] is nums[0].

4. Return value:

​ Returns the maximum value in the dp list, which represents the global maximum value.

Insert picture description here

public int maxSubArray1(int[] nums){
    
    //暴力破解2优化,O(n^2)
        int n = -100;
        for (int i = 1; i < nums.length; i++) {
    
    
            int sum = 0;
            for (int j = i; j <= nums.length; j++){
    
    
                sum += nums[j];
                if (sum > n){
    
    
                    n = sum;
                }
            }
        }
        return n;
    }
public int maxSubArray2(int[] nums){
    
    //动态规划
        
        //创建一个同样大小的数组dp[i]表示以元素num[i]为结尾的连续子数组最大和
        int[] dp = new int[nums.length];
        dp[0]=nums[0];//初始化dp[0]
        for(int j = 1;j<nums.length;j++){
    
    
            //判断条件,dp[j-1]>0表示以元素num[i]为结尾的连续子数组最大和大于0
            // 即可对之后组成更大的连续子数组有正贡献
            //dp[j-1]<0,表示以元素num[i]为结尾的连续子数组最大和小于0,
            // 不再参与之后的连续子数组,子数组从新积累
            if(dp[j-1]>0){
    
    
                dp[j] = dp[j-1]+nums[j];
            }else{
    
    
                dp[j] = nums[j];
            }
        }
        int max = Integer.MIN_VALUE;
        for(int i = 0;i<dp.length;i++){
    
    //遍历dp,找到最大值
            if(dp[i]>max)
                max = dp[i];
        }
        return max;
    }

public int maxSubArray3(int[] nums) {
    
    //同样的功能大佬的代码简单到离谱,阿巴阿巴
        int res = nums[0];
        for(int i = 1; i < nums.length; i++) {
    
    
            nums[i] += Math.max(nums[i - 1], 0);
            res = Math.max(res, nums[i]);
        }
        return res;
    }

public class MaxSubArray {
    
    
    public static void main(String[] args) {
    
    
        Solution solution = new Solution();
        int[] arr = new int[]{
    
    -2,1,-3,4,-1,2,1,-5,4};//结果为6,ok
        System.out.println(solution.maxSubArray3(arr));
    }
}

Summary: Getting started with dynamic programming. At the beginning, even the simplest brute force solution was not written independently. Now the idea of ​​solving these problems is suddenly clear, which is too powerful.

Brute force cracking is a double loop comparing the size of each sub-array sum, starting from 0 [0], [0,1], [0,1,2], until [0,1,2,...n], and then from Start at 1, [1],[1,2],[1,2,3] all the way to [1,2,...n], and then start at 2...

sum(0,0)
sum(0,1) sum(1,1)
sum(0,2) sum(1,2) sum(2,2)
sum(0,3) sum(1,3) sum(2,3)

--------------------------------------->

The dynamic programming idea of ​​this problem is to find the largest sub-array of each array ending in num[i] and store it in the array dp, and then traverse dp to find the maximum

Max
sum(0,0) dp[0]
sum(0,1) sum(1,1) dp[1]
sum(0,2) sum(1,2) sum(2,2) dp[2]
sum(0,3) sum(1,3) sum(2,3) dp[3]
dp[j]

Calculation method of maximum dp[j]

dp[j] = dp[j-1]+nums[j]; dp[j-1]>0

dp[j] = nums[j]; dp[j-1]<0

You can understand this method by calculating the examples given by yourself.

Guess you like

Origin blog.csdn.net/weixin_44529429/article/details/114136531