Use three interview questions to understand the basic logic of dynamic programming (the first appetizer)

Original title link: the maximum sum of consecutive sub-arrays

Click here to conquer the second way! ! !
Title description:

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

Source: LeetCode
Link: https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof
Copyright is owned by LeetCode . For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.

Question ideas:

1. A brief introduction to dynamic programming

Dynamic Programming (Dynamic Programming), referred to as dp, is a common strategy for solving optimization problems. Generally speaking, using dynamic programming to solve problems is nothing more than three steps.

1.1 Define the state (the state is the original problem, the solution of the sub-problem), such as defining the meaning of dp(i)

1.2 Set the initial state (boundary), such as setting the value of dp(0)

1.3 Determine the state transition equation, such as determining the relationship between dp(i) and dp(i-1)

2. So using these three steps, let us see how to solve the above problem.

2.1 Assuming that the value of nums is {-2,1,-3,4,-1,2,1,-5,4}, it is obvious that the maximum continuous subsequence sum is 4+(-1)+2+1 = 6

2.2 Define status

Assuming that dp(i) is the sum of the largest consecutive subsequence ending in nums[i], what does it mean? E.g

nums[0], the largest continuous subsequence at the end of -2 is -2, so dp(0) = -2

nums[1], the largest continuous subsequence at the end of 1 is 1, so dp(1) = 1

nums[2], the largest continuous subsequence at the end of -3 is 1, -3, so dp(2) = dp(1)+(-3) = -2

nums[3], the largest continuous subsequence at the end of 4 is 4, so dp(3) = 4

nums[4], the largest continuous subsequence at the end of -1 is 4, -1, so dp(4) = dp(3)+(-1) = 3

nums[5], the largest continuous subsequence at the end of 2 is 4, -1, 2, so dp(5) = dp(4) + 2 = 5

nums[6], the largest continuous subsequence at the end of 1 is 4, -1, 2, 1, so dp(6) = dp(5) + 1 = 6

nums[7], the largest continuous subsequence at the end of -5 is 4, -1, 2, 1, -5, so dp(7) = dp(6) + (-5) = 1

nums[8], the largest continuous subsequence at the end of 4 is 4, -1, 2, 1, so dp(6) = dp(7) + 4 = 5

So we can find the law. In fact, as long as the sum of the largest continuous subsequences in front is greater than 0, we need it. If it is less than or equal to 0, we don’t need it.

2.3 State transition equation

If dp(i-1) <= 0, then dp(i) = nums[i]; if dp(i-1)> 0, then dp(i) = dp(i-1) + nums[i];

2.4 Initial state

The value of dp(0) is nums[0]

2.5 So the final solution must be the maximum continuous subsequence and the maximum value in dp(i), that is, max{dp(i)}, i∈[0, nums.length)·

3. If it is too obscure, then I will explain it in plain English

For example, you are currently playing King of Glory. The elements in the nums[] array are the combat power of each player. In dp(i) is the strongest combat power of the team that ends with i. Because King of Glory is a team battle, you have to choose a team , Will you definitely choose a team with higher combat effectiveness to join? Lie down to win, who doesn’t want to, so once you encounter a team whose combat effectiveness is not greater than yours, that is, it is less than or equal to 0, don’t do it. The big one, you join the team, but oh, because if you add a team, others will also add it. There are some people whose combat power is less than 0 and those who are better than you want to hug your thighs. That kind of person is for your team. In other words, it is cumbersome, and you can’t judge the next person to join in, what is the combat effectiveness, so after all players have joined their respective teams, you will find that there must be the strongest combat team. At this time, you can Choosing to join them and join forces, isn't it a random killing? ! !

Don’t talk nonsense, just go to the code, in order to let the judges understand more clearly, my code is not written concisely, I add a lot of comments to the code, I believe that the judges can understand, if I did not write clearly or If you make a mistake, you can comment in the area or send a private message to me

class Solution {
    //记住一句话,递推就是由底向上的计算过程
    //假设dp(i)是以nums[i]结尾的最大连续子序列和(nums是整个序列)
    //例如dp[4]是以nums[4]结尾的最大连续子序列和
    public int maxSubArray(int[] nums) {
        //如果数组只有一个元素,那么最大和肯定只有这个元素了,就直接返回
        if(nums.length < 2) return nums[0];
        //取出第一个元素
        int dp = nums[0];
        //假设第一个元素是最大和
        int max = dp;
        for(int i = 1; i < nums.length; i++){    //遍历后面的元素 
            if(dp <= 0){    //如果遍历到某个元素,发现前面的最大连续子序列和是小于等0
            //那么这个元素就是当前的最大连续子序列和,因为很简单,前面都是负数了,我还要来干嘛,如果这个元素加上他们,岂不是更小了?所以不如不要
                dp = nums[i];
            }else{
                //发现前面的最大连续子序列和是大于0,那么我们就尝试把这个元素加进去
 /*
那可能会有这么个疑惑,假如当前元素是小于0呢?加进去岂不是会让之前的最大连续子序列和更小?其实不会,因为下面关于max代码就是会在max和dp取较大值,
由于在执行dp = dp + nums[i]之前,max肯定是之前的最大连续子序列和,所以即使当前元素是小于0也不怕,因为执行下面代码的时候,max应该是等于max而不是dp
*/
                dp = dp + nums[i];
            }
            //这里取较大和
            max = Math.max(max,dp);
        }
        //返回最大和
        return max;
    }
}

I've seen it all here, don't you think about clicking a like before leaving? If you don’t like it, my heart will be Bingbing.

 

Guess you like

Origin blog.csdn.net/qq_45798556/article/details/114844023