918. Maximum Sum of Circular Subarrays

Link to original title

Title description:

Please add a picture description

Example:

insert image description here

hint:

  • n == nums.length
  • 1 <= n <= 3 * 104
  • -3 * 104 <= nums[i] <= 3 * 104

Similar topic: Maximum subarray sum

Problem-solving ideas:

Method 1: Dynamic Programming

Since the array is circular, there are two situations in the situation of the largest subarray :

  • Case 1:

    ​The largest sub-array has only one segment, namely [i, j] { i >= 0 && j < len && i < j}

  • Case two:

    ​ There are two segments in the largest sub-array, [0, i] and [j, len - 1] { i < j}
    insert image description here

Situation one solution:

The solution for case 1 is the same as the largest subarray and also uses dynamic programming.

  1. Define the array dp = new int[len], where dp[i] represents the sum of the largest subarrays ending with subscript i .

  2. Derivation of the recursive formula:

    When traversing to subscript i , what should be the sum of the largest subarray ending with subscript i ?

    dp[i] depends on dp[i - 1] and nums[i], where dp[i - 1] represents the sum of the largest subarrays ending with subscript i - 1 , so dp[i] = dp[i - 1 ] + nums[i], but if nums[i] is larger than dp[i - 1] + nums[i], then dp[i] = nums[i], so dp[i] = Math.max( dp[i - 1] + nums[i], nums[i]).

  3. Initialize the array dp:

    Through the recursive formula, we can know that dp[i] is derived from the previous one, so dp[0] must be initialized, dp[0] = nums[0].

  4. Determine the traversal order:

    It can be traversed from front to back.

public int maxSumOfSubArray(int[] nums){
    
    
    int len = nums.length;
    int[] dp = new int[len];
    dp[0] = nums[0];
    int ans = dp[0];
    for(int i = 1; i < len; i++){
    
    
        dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
        ans = Math.max(dp[i], ans);  // 更新结果。
    }
    return ans;
}

Case two solution:

We need to record the maximum value of the interval [0, i], which starts from 0. For example, the maximum value of the interval [0, 2] is 10. If the sum of the interval [0, 3] is less than 10, then [0 , 3] interval is the value of [0, 2] interval.

Recording the maximum value of the interval [0, i] can be recorded in Case 1, as follows:

public int maxSumOfSubArray(int[] nums){
    
    
    int len = nums.length;
    int[] dp = new int[len];
    dp[0] = nums[0];
    int ans = dp[0];
    //=========记录[0, i]区间最大值===================
   	int[] leftSum = new int[len];
    leftSum[0] = nums[0];   
    int preSum = nums[0];
    //==============================================
    for(int i = 1; i < len; i++){
    
    
        dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
        ans = Math.max(dp[i], ans);  // 更新结果。
        //========记录[0, i]区间最大值==================
        preSum += nums[i]; // 记录[0, i] 区间的和。
        leftSum[i] = Math.max(leftSum[i - 1], preSum);
    }
    return ans;
}

Next, traverse the nums array in reverse order and record the sum of [j, len - 1]. The sum of [j, len - 1] plus leftSum[j - 1] is the sum of the largest subarray in case 2 .

The complete code is as follows:

public int maxSubarraySumCircular01(int[] nums) {
    
    
    int len = nums.length;
    int ans = nums[0];
    int[] dp = new int[len];
    dp[0] = nums[0];
    int[] leftSum = new int[len];
    leftSum[0] = nums[0];
    int preSum = nums[0];
    for (int i = 1; i < len; i++) {
    
    
        dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
        ans = Math.max(dp[i], ans);
        preSum += nums[i];
        leftSum[i] = Math.max(leftSum[i - 1], preSum);
    }

    int backSum = 0; // 记录[j, len - 1]的和
    for (int j = len - 1; j > 0; j--) {
    
    
        backSum += nums[j];
        ans = Math.max(ans, backSum + leftSum[j - 1]);
    }
    return ans;
}

おすすめ

転載: blog.csdn.net/qq_51134950/article/details/131830735