zoukankan      html  css  js  c++  java
  • [LeetCode] 918. Maximum Sum Circular Subarray 环形子数组的最大和


    Given a circular array C of integers represented by `A`, find the maximum possible sum of a non-empty subarray of C.

    Here, a circular array means the end of the array connects to the beginning of the array.  (Formally, C[i] = A[i] when 0 <= i < A.length, and C[i+A.length] = C[i] when i >= 0.)

    Also, a subarray may only include each element of the fixed buffer A at most once.  (Formally, for a subarray C[i], C[i+1], ..., C[j], there does not exist i <= k1, k2 <= j with k1 % A.length = k2 % A.length.)

    Example 1:

    Input: [1,-2,3,-2]
    Output: 3
    Explanation: Subarray [3] has maximum sum 3
    

    Example 2:

    Input: [5,-3,5]
    Output: 10 Explanation: Subarray [5,5] has maximum sum 5 + 5 = 10
    

    Example 3:

    Input: [3,-1,2,-1]
    Output: 4
    Explanation: Subarray [2,-1,3] has maximum sum 2 + (-1) + 3 = 4
    

    Example 4:

    Input: [3,-2,2,-3]
    Output: 3 Explanation: Subarray [3] and [3,-2,2] both have maximum sum 3
    

    Example 5:

    Input: [-2,-3,-1]
    Output: -1 Explanation: Subarray [-1] has maximum sum -1
    

    Note:

    1. -30000 <= A[i] <= 30000
    2. 1 <= A.length <= 30000

    这道题让求环形子数组的最大和,对于环形数组,我们应该并不陌生,之前也做过类似的题目 [Circular Array Loop](http://www.cnblogs.com/grandyang/p/7658128.html),就是说遍历到末尾之后又能回到开头继续遍历。假如没有环形数组这一个条件,其实就跟之前那道 [Maximum Subarray](http://www.cnblogs.com/grandyang/p/4377150.html) 一样,解法比较直接易懂。这里加上了环形数组的条件,难度就增加了一些,需要用到一些 trick。既然是子数组,则意味着必须是相连的数字,而由于环形数组的存在,说明可以首尾相连,这样的话,最长子数组的范围可以有两种情况,一种是正常的,数组中的某一段子数组,另一种是分为两段的,即首尾相连的,可以参见 [大神 lee215 的帖子](https://leetcode.com/problems/maximum-sum-circular-subarray/discuss/178422/One-Pass) 中的示意图。对于第一种情况,其实就是之前那道题 [Maximum Subarray](http://www.cnblogs.com/grandyang/p/4377150.html) 的做法,对于第二种情况,需要转换一下思路,除去两段的部分,中间剩的那段子数组其实是和最小的子数组,只要用之前的方法求出子数组的最小和,用数组总数字和一减,同样可以得到最大和。两种情况的最大和都要计算出来,取二者之间的较大值才是真正的和最大的子数组。但是这里有个 corner case 需要注意一下,假如数组中全是负数,那么和最小的子数组就是原数组本身,则求出的差值是0,而第一种情况求出的和最大的子数组也应该是负数,那么二者一比较,返回0就不对了,所以这种特殊情况需要单独处理一下,参见代码如下:
    class Solution {
    public:
        int maxSubarraySumCircular(vector<int>& A) {
            int sum = 0, mn = INT_MAX, mx = INT_MIN, curMax = 0, curMin = 0;
    		for (int num : A) {
    			curMin = min(curMin + num, num);
                mn = min(mn, curMin);
                curMax = max(curMax + num, num);
                mx = max(mx, curMax);
                sum += num;
    		}
            return (sum - mn == 0) ? mx : max(mx, sum - mn);
        }
    };
    

    Github 同步地址:

    https://github.com/grandyang/leetcode/issues/918


    类似题目:

    Maximum Subarray

    Circular Array Loop


    参考资料:

    https://leetcode.com/problems/maximum-sum-circular-subarray/

    https://leetcode.com/problems/maximum-sum-circular-subarray/discuss/178422/One-Pass


    [LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)
  • 相关阅读:
    PHP-表单提交(form)
    JavaWeb-tomcat安装(Unsupported major.minor version 51.0/startup.bat闪退)
    答疑解惑
    IT路上可能遇到的小需求资源汇总
    批量定时任务将rtf文件转为docx,入参是rtf文件夹,生成一个docx文件夹
    Elastic Search快速入门
    https原理和如何配置https
    开源Futter项目
    如何触发react input change事件
    sqlserver 之 将查询结果变为json字符串
  • 原文地址:https://www.cnblogs.com/grandyang/p/11716314.html
Copyright © 2011-2022 走看看