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)

[LeetCode] 918. Maximum Sum Circular Subarray 环形子数组的最大和的更多相关文章

  1. LC 918. Maximum Sum Circular Subarray

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

  2. 918. Maximum Sum Circular Subarray

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

  3. Leetcode Week5 Maximum Sum Circular Subarray

    Question Given a circular array C of integers represented by A, find the maximum possible sum of a n ...

  4. [Swift]LeetCode918. 环形子数组的最大和 | Maximum Sum Circular Subarray

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

  5. Maximum Sum Circular Subarray LT918

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

  6. [LeetCode] 907. Sum of Subarray Minimums 子数组最小值之和

    Given an array of integers A, find the sum of min(B), where B ranges over every (contiguous) subarra ...

  7. 动态规划-Maximum Subarray-Maximum Sum Circular Subarray

    2020-02-18 20:57:58 一.Maximum Subarray 经典的动态规划问题. 问题描述: 问题求解: public int maxSubArray(int[] nums) { i ...

  8. [LeetCode] Maximum Sum of 3 Non-Overlapping Subarrays 三个非重叠子数组的最大和

    In a given array nums of positive integers, find three non-overlapping subarrays with maximum sum. E ...

  9. [LeetCode] 689. Maximum Sum of 3 Non-Overlapping Subarrays 三个非重叠子数组的最大和

    In a given array nums of positive integers, find three non-overlapping subarrays with maximum sum. E ...

随机推荐

  1. 快速认识springcloud微服务

    这周浅显的学习了springcloud.简单聊一下微服务.所谓的微服务远远没有我想想的那么高端难以理解,简单说,就是多个服务分布在不同的服务器上,由这些服务互相配合完成某一项任务.那服务和服务之间调用 ...

  2. Shell基本运算符之文件测试符

    文件测试运算符 ================摘自菜鸟教程================= 文件测试运算符用于检测UNIx文件的各种属性: 操作符 说明 例子 -b 检测文件是否是块设备文件,如果 ...

  3. poj-2803 Defining Moment

    Defining Moment Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1660   Accepted: 760 De ...

  4. h5中的audio音频标签与对应的dom对象

    HTML5中提供了一个<audio>标签,同时也提供了一个Audio对象给JavaScript去操作,这个对象属于HTML的DOM对象. H5中的<audio>标签 此标签是H ...

  5. duba网址对firefox快捷方式的劫持

    直接删除 “驱动精灵” 即可. 等我 二进制安全 学好了,一定开发一种病毒专干这种劫持的,煞笔软件.

  6. springcloud分布式事务Atomikos实例

    0.JTA(Java Transaction Manager)的介绍 (1)jta与jdbc 简单的说 jta是多库的事务 jdbc是单库的事务 (2)XA与JTA XA : XA是一个规范或是一个事 ...

  7. 使用jqPrint.js调用浏览器打印界面,打印网页中的某一部分该部分含有ECharts图表

    1.准备好js文件(我用的是谷歌浏览器) 这个文件是为了防止你的jQuery版本过高而不适配的问题 这是调用浏览器打印的js插件 2.引入js文件 <script src="js/jq ...

  8. FMDB的操作

    #import "ZYDataManager.h" #import "JSSportModel.h" FMDatabase *db = nil; @implem ...

  9. 【转】Git使用教程之BUG分支

    1.bug分支 在开发中,会经常碰到bug问题,那么有了bug就需要修复,在Git中,分支是很强大的,每个bug都可以通过一个临时分支来修复,修复完成后,合并分支,然后将临时的分支删除掉. 比如我在开 ...

  10. 用SignApk.jar对APK进行签名

    对apk签名需要使用SignApk.jar和签名文件.可以使用Android源码获取,若没有源码,可以在这下载:SignApk.jar.(包含了SignApk.jar和签名文件和批处理文件) 1 Si ...