题目
小美请小团吃回转寿司。转盘上有N盘寿司围成一圈,第1盘与第2盘相邻,第2盘与第3盘相邻,…,第N-1盘与第N盘相邻,第N盘与第1盘相邻。小团认为第i盘寿司的美味值为A[i](可能是负值,如果小团讨厌这盘寿司)。现在,小团要在转盘上选出连续的若干盘寿司,使得这些寿司的美味值之和最大(允许不选任何寿司,此时美味值总和为0)。
输入描述:
第一行输入一个整数T(1<=T<=10),表示数据组数。
每组数据占两行,第一行输入一个整数N(1<=N<=10^5);
第二行输入N个由空格隔开的整数,表示A[1]到A[N](-104<=A[i]<=104)。
输出描述:
每组数据输出占一行,输出一个整数,表示连续若干盘寿司的美味值之和的最大值。
示例1
输入
1
4
3 -2 4 -1
输出
6
说明
美味值之和最大连续若干盘寿司为第3盘、第4盘和第1盘。
题解
本来以为是求数组的是最大和, 可以考虑动态规划, 但是看到需要收尾相接, 那么基础还是求最大和, 只是需要处理环的链接部分.
环的部分难点在于, 单向计算数组的最大和的回头问题, 最开始想的是, 原有数组基础上后面追加一遍数组元素, 营造一个假的环
, 但是, 还要处理最大连续的个数, 感觉绕进了一个死胡同.
于是乎这里有一个巧妙地思路:
最大连续和 + 最小连续和 = 总数和
上述两个和是互斥的而且紧密相连
所以,
- 如果最大连续和是跨
环节点
的, 那么就用 `总数 - 最小连续 - 如果最大连续和不是跨节点, 那么取求出的最大连续
代码
代码只是核心部分, 题目中提到的组数, 这里只是一组的代码, 多组可以添加上wihle循环.
func maxSum(_ array: Array<Int>?) -> Int {
guard let data = array else {
return 0
}
var dpMax: Int = data[0]
var _max : Int = data[0]
var dpMin: Int = data[0]
var _min: Int = data[0]
var sum: Int = data[0]
for index in 1..<data.count {
let cur = data[index]
sum += cur
dpMax = max(dpMax + cur, cur)
_max = max(_max, dpMax)
dpMin = min(dpMin + cur, cur)
_min = min(_min, dpMin)
}
print(sum, _max, _min)
return max(sum - _min, _max)
}
无奈
牛客上的笔试部分的输入, 一直不知道该怎么办, 有大佬知道该怎么做吗???