zoukankan      html  css  js  c++  java
  • [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;
        }
    }
  • 相关阅读:
    生成器函数
    初识函数
    格式化输出
    流程控制-while循环
    流程控制if语句
    Python入门
    Eclipse搭建C++开发环境
    Android SQLite基本用法
    Android拍照后更新相册
    操作系统相册和获取相册路径
  • 原文地址:https://www.cnblogs.com/lz87/p/11525139.html
Copyright © 2011-2022 走看看