【LeetCode】Dynamic programming training (7)

918. Maximum Sum of Circular Subarrays

Click to view: Maximum sum of circular subarrays


Given a circular integer array nums of length n, return the largest possible sum of non-empty subarrays of nums.
A circular array means that the end of the array will be connected to the beginning in a ring. Formally, the next element of nums[i] is nums[(i + 1) % n] and the previous element of nums[i] is nums[(i - 1 + n) % n] .
The subarray may contain each element in the fixed buffer nums at most once. Formally, for subarrays nums[i], nums[i + 1], …, nums[j], there is no i <= k1, k2 <= j where k1 % n == k2 % n.

Example 1:
Input: nums = [1,-2,3,-2]
Output: 3
Explanation: Get maximum sum of 3 from subarray [3]
Example 2:
Input: nums = [5,-3,5]
Output: 10
Explanation: Get the maximum sum from the subarray [5,5] 5 + 5 = 10

topic analysis

You can only take 3, or take 3 and -2
because the array is circular, so take 1 and -2 on the basis of 3 and -2
and compare, take 3 to be the maximum sum


state transition equation

First convert the circular array to an ordinary array, and then solve


Case 1:

If you want to get the maximum sum of the current array, you only need to take 3. Then
the maximum sum of the current array is inside the array, and the array can be regarded as an ordinary array in the current situation. You can use the
solution of the maximum sub-array sum to solve the current problem


Case 2:

If you want to take the maximum sum of the current array, you need to take the sum of the last 5 and the previous 5
arrays of the ring connection as a fixed value. If you want to take the maximum value of the current red area, you need to take the minimum value of the blank area.
Due to red The area is discontinuous, and the blank area is a continuous interval,
so you can first find the minimum subarray sum of the blank area and
then subtract the minimum array sum of the blank area from the overall array sum to obtain the maximum subarray sum of the red area


The maximum subarray sum of case 1 is denoted by f
The minimum subarray sum of case 2 is denoted by g

f[i]: indicates the maximum sum of all subarrays ending with i g[i]: indicates the minimum sum of all subarrays ending with i

f[i] state transition equation

Divide the subarray into two classes

1. The element at position i itself (length 1)
in this case: f[i]=nums[i]

2. The element at position i plus the combination of the previous elements (length greater than 1) is

required because the maximum sum of the sub-arrays ending at position i is required, so the maximum sum of the sub-arrays ending at position i-1 should be first calculated, that is, f [ i-1]
plus nums[i], it is the maximum sum of sub-arrays ending at position i
In this case: f[i]=f[i-1]+nums[i]


The state transition equation is:
f[i]=max(nums[i],f[i-1]+nums[i])

g[i] state transition equation

The difference between g[i] and f[i] is that f[i] wants the maximum value, while g[i] wants the minimum value, and other analyzes are the same


g[i] can be divided into two categories

Case 1: The i position element itself (length is 1)
In this case: g[i]=nums[i]

Case 2: The element at position i is combined with the previous element (the length is greater than 1). If

you want to find the smallest subarray sum ending with i, you need to first find the smallest subarray sum ending with i-1, that is, g[i-1]
in Adding nums[i] is the smallest subarray ending with i and
in this case: g[i]=g[i-1]+nums[i]


The state transition equation is:
g[i]=min(nums[i],g[i-1]+nums[i])

initialization

According to the state transition equation, if i is 0, an out-of-bounds problem will occur

In order to prevent this kind of out-of-bounds problem, a virtual node is added to
the expanded array. The subscript of the virtual node is 0, and the element subscript of the original array starts from 1.


For the f[i] state transition equation, if i is 1, then f[1]=max(nums[1],f[0]+nums[1]) Since the subscript is 0 is a virtual node,
so f[0] should not interfere with the result, so set f[0] to 0


For the g[i] state transition equation, if i is 1, then g[1]=max(nums[1],g[0]+nums[1]) Since the subscript is 0 is a virtual node,
so g[0] should not interfere with the result, so set g[0] to 0

return value

For the two cases at the beginning of the analysis,
case 1
takes the maximum value in the f table, that is, fmax
fmax, that is, the maximum subarray sum of case 1


In case 2,
take the minimum value in the g table, that is, gmin
. Since the maximum subarray sum of the red area in case 2 is the whole array minus the white area subarray sum, the
maximum subarray sum of case 2 is sum-gmin

The maximum subarray sum of a ring array is: max(fmax,sum-gmin)


g is a continuous sub-array, and the sum is the smallest, so gmin is the smallest sum when all three elements of the current array are added.
Using sum-gmin, it will result in the largest sub-array sum of case 2 being 0,
so that the final circular array is obtained. When the largest subarray sum of is expected to be the largest negative number, the result is 0, causing an error


Therefore, it is necessary to add a judgment condition
if sum==gmin (the elements in the array are all negative), just return fmax directly
. If the above judgment is not true, return max(fmax,sum-gmin)

full code

class Solution {
    
    
public:
    int maxSubarraySumCircular(vector<int>& nums) {
    
    
       int n=nums.size();
       //为了防止越界问题,所以多开辟一个空间
       vector<int>f(n+1,0);
       vector<int>g(n+1,0);
       //初始化
       f[0]=0;
       g[0]=0;
       int i=0;

       //sum为整体数组和
       int sum=0;
       for(i=0;i<n;i++)
       {
    
    
         sum+=nums[i];
       }
         //取f表中的最大值
       int fmax=INT_MIN;
         //取g表中的最小值
       int gmin=INT_MAX;
       for(i=1;i<=n;i++)
       {
    
    
           //由于当前下标为扩展数组f/g的下标
           //想要使用当前下标 去寻找 对应nums的值
           //需要下标减1
           f[i]=max(nums[i-1],f[i-1]+nums[i-1]);
           g[i]=min(nums[i-1],g[i-1]+nums[i-1]);
           fmax=max(fmax,f[i]);
           gmin=min(gmin,g[i]);
       }
        //有可能存在数组元素全为负的情况,所以需要判断
        return sum==gmin?fmax:max(fmax,sum-gmin);
    }
};

152. Product Maximum Subarray

Click to view: Maximum product subarray


Given an integer array nums, please find the non-empty continuous subarray with the largest product in the array (the subarray contains at least one number), and return the product corresponding to the subarray.
The answer to the test case is a 32-bit integer.
A subarray is a contiguous subsequence of an array.

Example 1:
Input: nums = [2,3,-2,4]
Output: 6
Explanation: Subarray [2,3] has maximum product 6.
Example 2:
Input: nums = [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.

topic analysis

Take the product of 2 and 3 as the maximum product of the subarray,
and the product becomes 6

If you take -2 on this basis, multiplying a negative number will result in smaller and smaller
multiplications, and the product becomes -12

state transition equation

f[i]: indicates the maximum product of all subarrays ending at position i
g[i]: indicates the minimum product of all subarrays ending at position i

f[i] state transition equation

f[i] can be divided into two categories:

Case 1: The element itself at position i (length 1)
In this case: f[i]=nums[i]

Case 2: The element at position i is combined with the previous element (length greater than 1)

Case 1 If nums[i] is greater than 0 and
you want to find the maximum product at position i, you must first find the maximum product at position i-1, which is f[i -1]
and then multiplied by nums[i], that is, when nums[i] is greater than 0, the maximum product at position i
is f[i]=f[i-1]*nums[i]

Case 2 If nums[i] is less than 0
, if nums[i] is negative, and f[i-1] is the maximum product ending with i-1, it will cause the smaller the multiplication, so it needs to be multiplied by one in
front The minimum product will make the two multiply more and more , that is, the minimum product g[
i-1] of all sub-arrays ending with i-1 is multiplied by nums[i], that is, when nums[i] is less than 0, The maximum product at position i is f[i]=g[i-1]*nums[i]

The state transition equation is:
f[i]=max(nums[i] , max(f[i-1]*nums[i],g[i-1]*nums[i]) )

g[i] state transition equation

Case 1 element at position i (length 1)
g[i]=nums[i]


Case 2 The element at position i is combined with the previous element (length greater than 1)

If nums[i] is greater than 0
and you want to find the minimum product at position i, you must first find the minimum product at position i-1, that is, g[i-1] and
then multiply it by nums[i], that is, nums[i] is greater than 0 In this case, the minimum product at position i
is g[i]=g[i-1]*nums[i]


If nums[i] is less than 0
, if you want to find the minimum product at position i, you must first find the maximum product at position i-1, that is, f[i-1]
and then multiply it by nums[i], that is, nums[i] is less than 0 In this case, the minimum product at position i
is g[i]=f[i-1]*nums[i]


The state transition equation is:
g[i]=min(nums[i] ,min(g[i-1]*nums[i],f[i-1]*nums[i]) )

initialization

If i is 0, an out-of-bounds problem will occur

When i is 1,
g[1]=min(nums[1],min(g[0]*nums[1],f[0]*nums[1]))
in order not to let f[0] or g[ 0] interferes with the result, so set both f[0] and g[0] to 1

full code

class Solution {
    
    
public:
    int maxProduct(vector<int>& nums) {
    
    
       int n=nums.size();
       //为了防止越界问题,所以进行将数组多加一个虚拟节点
       vector<int>f(n+1,0);
       vector<int>g(n+1,0);
       //初始化
       f[0]=1;
       g[0]=1;
       int i=0;
       int ret=INT_MIN;
       for(i=1;i<=n;i++)
       {
    
    
           //当前下标为扩展数组f/g的下标
           //想要使用当前下标 去寻找对应的原数组的值
           //需要将下标减1
           f[i]=max(nums[i-1],max(f[i-1]*nums[i-1],g[i-1]*nums[i-1]));
           g[i]=min(nums[i-1],min(g[i-1]*nums[i-1],f[i-1]*nums[i-1]));
           ret=max(ret,f[i]);
       }
       return ret;
    }
};

Because the return value is the maximum product, you only need to return the maximum value in the f table

1567. Length of Longest Subarray with Positive Product

Click to view: The length of the longest subarray whose product is a positive number


Given an integer array nums, please find the length of the longest subarray whose product is a positive number.
A subarray of an array is an array of zero or more consecutive numbers in the original array.
Please return the length of the longest subarray whose product is a positive number.

Example 1:
Input: nums = [1,-2,-3,4]
Output: 4
Explanation: The product of the array itself is a positive number with a value of 24.
Example 2:
Input: nums = [0,1,-2,-3,-4]
Output: 3
Explanation: The subarray whose longest product is a positive number is [1,-2,-3], and the product is 6.
Note that we cannot also include 0 in the subarray, because the product would be 0, which is not a positive number.

topic analysis

The sub-arrays must be continuous, and the product of the sub-arrays is positive. Find which one of the sub-arrays with the longest product is the longest

Choose the product 1 -2 -3, the product is positive, the length is 3
choose the product -2 -3 4, the product is positive, the length is 3
choose the product 1 -2 -3 4, the product is positive, the length is 4
so Maximum length is 4

state transition equation

f[i]: Indicates the longest length of a positive product in all subarrays ending at position i g[i]: Indicates the longest length of a negative product in all subarrays ending at position i

f[i] state transition equation

Case 1 The element itself at position i (length 1)

If num[i] is greater than 0, then f[i] is 1
If nums[i] is less than 0, then f[i] is 0


Case 2 i position element plus the combination of the previous element (length greater than 1)

If nums[i[ is greater than 0, it needs to be multiplied by the longest length whose product is a positive number

If you want to find the longest length of all sub-arrays ending with position i, the product of which is a positive number, because nums[i] is greater than 0, you need to find the longest length of all sub-arrays ending at position i-1 where the product is a positive number The long length is the length of f[i-1]
after adding the i position, which is +1

In this case: f[i]=f[i-1]+1


If nums[i] is less than 0, it needs to be multiplied by the longest length of the negative number

In this way, the overall product can be guaranteed to be a positive number

If you want to find the longest length of all subarrays ending with position i, the product of which is a positive number, because nums[i] is less than 0, you need to first find the longest length of all subarrays ending at position i-1 with a negative product The length is the length of g[i-1]
after adding the i position, which is +1

If it is directly written as f[i]=g[i-1]+1,
if the products ending with i-1 in the array are all greater than 0, and the i position is less than 0, then there is no way to generate a length whose product is a positive number, and the expected result is 0, and the value of f[i] is 1, resulting in an error.
Therefore, it is necessary to first judge whether g[i-1] is equal to 0 (if it is equal to 0, it means that all products ending with i-1 are greater than 0)
if g[i-1] ] is equal to 0, then f[i]=0
If g[i-1] is not equal to 0, then f[i]=g[i-1]+1
that is f[i] =g[i-1]== 0?0:g[i-1]+1


The state transition equation is:
if(nums[i]>0)
f[i]=f[i-1]+1

if(nums[i]<0)
f[i]=g[i-1]==0?0:g[i-1]+1

g[i] state transition equation

Case 1 length is 1

g[i] represents the longest length of negative products in all subarrays ending with i.
If nums[i] is greater than 0, then g[i] is 0.
If nums[i] is less than 0, then g[i] is 1.


Case 2 length is greater than 1

If nums[i] is greater than 0, it needs to be multiplied by the longest length whose product is negative
to make the overall array product negative

Want to find the longest length of negative product in all sub-arrays ending at position i, because nums[i] is greater than 0, you need to find the longest length of negative product in all sub-arrays ending at position i-1 That is, the length of g[i-1]
at the position i after adding it is +1

If it is directly written as g[i]=g[i-1]+1,
if the products ending with i-1 in the array are all greater than 0, and the i position is greater than 0, then there is no way to generate a length whose product is a negative number, and the expected result is 0, the value of f[i] is 1, resulting in an error,
so it is necessary to judge whether g[i-1] is equal to 0 (if it is equal to 0, it means that the products ending with i-1 are all greater than 0)
if g[i-1] Equal to 0, then g[i]=0
If g[i-1] is not equal to 0, then g[i]=g[i-1]+1
that is g[i] =g[i-1]==0 ?0:g[i-1]+1


If nums[i] is less than 0, it needs to be multiplied by the longest length whose product is positive

If you want to find the longest length of all subarrays ending with position i whose product is a negative number, because nums[i] is less than 0, you need to first find the longest length of all subarrays ending at position i-1 with a positive product The length is the length of f[i-1]
after adding the i position, which is +1

In this case: g[i]=f[i-1]+1


The state transition equation is:
if(nums[i]>0)
g[i]=g[i-1]==0?0:g[i-1]+1

if(nums[i]<0)
g[i]=f[i-1]+1

initialization

If i is 0, an out-of-bounds problem will occur

When nums[i] is less than 0, if i is 1, then g[1]=f[0]+1
In order not to let f[0] interfere with the result, so set f[0]=0


Since the current subscript is the subscript of the f/g extended array,
if you want to use the current subscript to find the value corresponding to nums,
you need to subtract 1 from the subscript
, so when i is 1, take the value of nums[0], if nums[ 0]>0, then g[0]==0
(g[0] represents the longest length of the negative product of all subarrays ending with the subscript 0)
nums[0] is greater than 0, indicating that there is no case where the product is negative , so g[0] takes 0

full code

class Solution {
    
    
public:
    int getMaxLen(vector<int>& nums) {
    
    
       int n=nums.size();
       //为了避免越界问题,所以设置一个虚拟节点
       vector<int>f(n+1,0);
       vector<int>g(n+1,0);
       //初始化
       f[0]=0;
       g[0]=0;
       int i=0;
       int ret=INT_MIN;
       for(i=1;i<=n;i++)
       {
    
    
           //由于当前使用下标为f/g扩展数组的下标
           //所以想要使用当前下标 ,寻找到对应nums的值
           //需要下标减1
            if(nums[i-1]>0)
            {
    
    
                f[i]=f[i-1]+1;
                g[i]=g[i-1]==0?0:g[i-1]+1;
            }
            else if(nums[i-1]<0)
            {
    
    
                f[i]=g[i-1]==0?0:g[i-1]+1;
                g[i]=f[i-1]+1;
            }
            ret=max(ret,f[i]);
       }
       //返回 f表中的最大值
       return ret;
    }
};

Since the f table represents the longest length of the subarray whose product is positive, return the maximum value of the f table

Guess you like

Origin blog.csdn.net/qq_62939852/article/details/131482013