[LeetCode 1186] Maximum Subarray Sum with One Deletion

Given an array of integers, return the maximum sum for a non-empty subarray (contiguous elements) with at most one element deletion. In other words, you want to choose a subarray and optionally delete one element from it so that there is still at least one element left and the sum of the remaining elements is maximum possible.

Note that the subarray needs to be non-empty after deleting one element.

 

Example 1:

Input: arr = [1,-2,0,3]
Output: 4
Explanation: Because we can choose [1, -2, 0, 3] and drop -2, thus the subarray [1, 0, 3] becomes the maximum value.

Example 2:

Input: arr = [1,-2,-2,3]
Output: 3
Explanation: We just choose [3] and it's the maximum sum.

Example 3:

Input: arr = [-1,-1,-1,-1]
Output: -1
Explanation: The final subarray needs to be non-empty. You can't choose [-1] and delete -1 from it, then get an empty subarray to make the sum equals to 0.

 

Constraints:

  • 1 <= arr.length <= 10^5
  • -10^4 <= arr[i] <= 10^4

 

A variation of Kadane's Algorithm to get maximum subarray sum. 

The final answer must be one of the following 2 cases.

1. No element is deleted. This is equivalent with maximum subarray sum.

2. One element is deleted. We can reduce this to finding a maximum sum of two separated subarrays, endAt[i - 1] and startAt[i + 1], arr[i] is deleted.  endAt[i - 1] is already computed in case 1. So we just need to apply Kadane's algorithm again to compute startAt[i + 1]. startAt is the same with endAt if we iterate arr from right to left. 

 

A few cases to think about when finding the max result. 

1. Do we need to find the max when computing the startAt max subarray results array?  No, because every startAt is a mirror of another endAt, which has already computed its max result. 

2. For case 2 of separated subarrays, we only need to consider the case that both left and right subarrays are not empty. This is true because if the left subarray is empty, then it becomes an startAt with no deletion; similarly if the right subarray is empty, then it becomes an endAt with no deletion. Both of these two cases have been covered.

 

class Solution {
    public int maximumSum(int[] arr) {
        int n = arr.length, res = arr[0];
        int[] maxEndAt = new int[n];
        int[] maxStartAt = new int[n];
        maxEndAt[0] = arr[0];
        for(int i = 1; i < n; i++) {
            maxEndAt[i] = Math.max(maxEndAt[i - 1] + arr[i], arr[i]);
            res = Math.max(res, maxEndAt[i]);
        }
        maxStartAt[n - 1] = arr[n - 1];
        for(int i = n - 2; i >= 0; i--) {
            maxStartAt[i] = Math.max(arr[i] + maxStartAt[i + 1], arr[i]);
        }
        for(int i = 1; i < n - 1; i++) {
            if(arr[i] < 0) {
                res = Math.max(res, maxEndAt[i - 1] + maxStartAt[i + 1]);
            }            
        }
        return res;
    }
}



 

This problem is similar with Product of Array Except Self in regard with the separated left and right DP arrays.

 

Given an array nums of n integers where n > 1,  return an array output such that output[i] is equal to the product of all the elements of nums except nums[i].

Example:

Input:  [1,2,3,4]
Output: [24,12,8,6]

Note: Please solve it without division and in O(n).

 

class Solution {
    public int[] productExceptSelf(int[] nums) {
        if(nums == null || nums.length <= 1) {
            return nums;
        }
        int[] leftProduct = new int[nums.length];
        leftProduct[0] = nums[0];
        for(int i = 1; i < nums.length; i++) {
            leftProduct[i] = leftProduct[i- 1] * nums[i];
        }
        int[] rightProduct = new int[nums.length];
        rightProduct[nums.length - 1] = nums[nums.length - 1];
        for(int i = nums.length - 2; i >= 0; i--) {
            rightProduct[i] = rightProduct[i + 1] * nums[i];
        }
        int[] productArray = new int[nums.length];
        productArray[0] = rightProduct[1];
        productArray[nums.length - 1] = leftProduct[nums.length - 2];
        for(int i = 1; i < nums.length - 1; i++) {
            productArray[i] = leftProduct[i - 1] * rightProduct[i + 1];
        }
        return productArray;
    }
}

 

posted @ 2019-09-16 23:31  Review->Improve  阅读(1085)  评论(0编辑  收藏  举报