leetcode 918 ring maximum subsequence sum

Posted by bickyz on Fri, 14 Jan 2022 20:10:51 +0100

Unlike the sum of the largest subsequences of an ordinary array, one state transition equation can solve all the problems. The ring subsequence increases the possibility of more optimal values, such as sequence [5, - 3, 5]. If the former, the maximum value is 7. If the front and rear end sequences can be connected, the maximum value should be 10

Train of thought I

In fact, we can divide the problem into two situations
1. One is the sum of continuous maximum subsequences of common type, according to dp[i] = num [i] > 0? dp[i-1] + nums [i]: nums [i], where dp[i] is the maximum value of the subsequence ending with the ith element. In this way, traverse the array, constantly update dp[i] and update the optimal value ans. after traversing the array, the sum of the largest subsequence of a continuous section is ans. this dynamic programming algorithm for solving the maximum value of a continuous subsequence is also called Kadane algorithm
2. The second is the case of head to tail connection, that is, the array is divided into three consecutive intervals. What we require is the sum of all elements in the first and third intervals, so that T[i,j] is the sequence sum with i as the end subscript of the first interval and j as the beginning subscript of the third interval, T[i,j]=nums[0,i]+nums[j,length-1], where i + 1 < j
3. To obtain the maximum value of T[i,j], we further modify the expression of T[i,j]
T[i,j]=nums[0,i]+rightmax[j,length-1];
Rightmax[j,length-1]=max{nums[j,length-1],Rightmax[j+1,length-1]} i+1<j<length-2
4. Finally, the maximum value can be obtained by comparing the ans of the former with the ans of the latter

My code:

class Solution {
public:
    int maxSubarraySumCircular(vector<int>& nums) {
    int length=nums.size();
    int last=nums[0];
    int ans=last;
    for(int i=1;i<length;i++)
    {
        if(last>0)
        {
            last=last+nums[i];
        }
        else
        {
            last=nums[i];
        }
        ans=ans>last?ans:last;
    }

    int *right=new int[length];
    right[length-1]=nums[length-1];
    for(int i=length-2;i>0;i--)
    {
        right[i]=right[i+1]+nums[i];
    }

    int *right_max=new int[length];
    right_max[length-1]=nums[length-1];
    for(int i=length-2;i>0;i--)
    {
        right_max[i]=right[i]>right_max[i+1]?right[i]:right_max[i+1];
    }

    int left=0;
    for(int i=0;i<length-2;i++)
    {
        left+=nums[i];
        if(left+right_max[i+2]>ans)
            ans=left+right_max[i+2];
    }
    return ans;
    }
};

Train of thought II

1. Similarly, we still need to divide the problem solving into two parts and compare a continuous case and two separate cases
2. The situations and ideas of a continuous section are solved one by one, which will not be described here.
3. For the case where two segments are separated, we can use the reverse way of thinking to solve it. It is required that the maximum value of T [I, J] = num [0, I] + num [J, length-1], that is, the maximum value of T[i,j]=S-sum[i+1,j-1], where S is the sum of sequences and sum[i,j] is the sum of elements I to j, which is transformed into the small value of solving sequences | i+1, j-1 |, The minimum continuous subsequence sum can be solved by Kadane algorithm
4. Finally, it can be solved by comparing the maximum values of the two cases

My code:

class Solution {
public:
    int getminmax(vector<int>& nums,int start,int end,int sort_type)
    {
        if(start>end)
            return 0;
        int ans=nums[start];
        int last=nums[start];
        for(int i=start+1;i<=end;i++)
        {
            if(sort_type==0)
            {
                last=last<0?last+nums[i]:nums[i];
                ans=last<ans?last:ans;
            }
            else
            {
                last=last>0?last+nums[i]:nums[i];
                ans=last>ans?last:ans;
            }
        }
        return ans;
    }
    int maxSubarraySumCircular(vector<int>& nums) {
    int length=nums.size();
    int ans=getminmax(nums,0,length-1,1);
    int total=0;
    for(int i=0;i<length;i++)
    {
        total+=nums[i];
    }
    int ans1=total-getminmax(nums,1,length-2,0);
    return ans>ans1?ans:ans1;
    }
};

Topics: leetcode