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;
        }
    }
  • 相关阅读:
    iOS开发笔记18:一些编译、开发调试、打包的细节整理
    iOS开发笔记17:自定义相机拍照
    iOS开发笔记15:地图坐标转换那些事、block引用循环/weak–strong dance、UICollectionviewLayout及瀑布流、图层混合
    iOS开发笔记14:微博/微信登录与分享、微信/支付宝支付
    iOS开发笔记13:顶部标签式导航栏及下拉分类菜单
    iOS开发笔记12:iOS7上UITextField限制字数输入导致崩溃问题
    iOS开发笔记11:表单键盘遮挡、浮点数价格格式化显示、省市区选择器、View Debugging
    iOS开发笔记10:圆点缩放动画、强制更新、远程推送加语音提醒及UIView截屏
    iOS开发笔记9:NSUserDefaults存储自定义实体对象
    iOS开发笔记8:Remote Notification远程消息推送处理
  • 原文地址:https://www.cnblogs.com/lz87/p/11525139.html
Copyright © 2011-2022 走看看