2023-07-20 Leetcode 918 环形数组的最大和

94 阅读1分钟

Problem: 918. 环形子数组的最大和

思路

和最大子数组和很类似,这种无后效性的问题一般可以通过DP来解决

解题方法

  1. 不存在环形,那么ans = maxS
  2. 最大子数组和位于环形中,那么剩余部门一定是连续子数组,且sum - maxS = minS
  3. 分别求出maxS, minS
  4. 需要特别注意,当数组元素均为负时,minS == sum,此时 sum - minS 其实是空,所以此时应该返回maxS

Code


class Solution {
    public int maxSubarraySumCircular(int[] nums) {
        int sum = 0;
        for (int i = 0; i < nums.length; i++) sum += nums[i];
        int min = minSubArray(nums);
        int max = maxSubArray(nums);
        if (sum == min) return max;
        return Math.max(max, sum - min);
    }
    // 最小子数组和
    public int minSubArray(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n];
        dp[0] = nums[0];

        int ans = dp[0];
        for (int i = 1; i < n; i++) {
            dp[i] = Math.min(nums[i], dp[i-1] + nums[i]);
            ans = Math.min(ans, dp[i]);
        }

        return ans;
    }
    // 最大子数组和
    public int maxSubArray(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n];
        dp[0] = nums[0];

        int ans = dp[0];
        for (int i = 1; i < n; i++) {
            dp[i] = Math.max(nums[i], dp[i-1] + nums[i]);
            ans = Math.max(ans, dp[i]);
        }

        return ans;
    }
}