- 题目要求:
-
思路:
- 题中给的虽然是环形的,一开始想到的一定是遍历从头至尾再遍历一遍
- 这道题遍历一遍,找到所有元素的和sum,最大的子序和,和最小的子序和
- 如果sum小于0而且等于最小的子序和,说明数组元素都为负,返回最大子序和
- 如果不是上述情况,通过比较,如果sum-最小的子序和>最大的子序和,说明最大的子序和在数组的首尾都有,那么返回sum-最小的子序和,反之返回最大子序和
- 核心代码:
#定义五个值,分别是临时的最大子串和,临时的最小子串和,全局的最小子串和,全局的最大子串和和数组所有元素之和
localmax = A[0]
localmin = A[0]
finalmin = A[0]
finalmax = A[0]
summ = A[0]
#因为五个值的初始值都赋为A[0],所以遍历从下标1开始
for i in range(1,len(A)):
#总和加上当前的值
summ += A[i]
#如果当前的值加上临时的最大子串和比当前的值大,把当前的值加上临时的最大子串和赋给临时的最大子串和
if localmax + A[i] > A[i]:
localmax += A[i]
#如果没有当前的值大,说明当前的值是临时的最大子串和
else:
localmax = A[i]
#把当前最大子串和和全局最大子串和中较大的那个赋给全局最大子串和
finalmax = max(localmax , finalmax)
#最小子串和也是一样的
if localmin + A[i] < A[i]:
localmin += A[i]
else:
localmin = A[i]
finalmin = min(localmin , finalmin)
#如果所有元素的和等于全局的最小子串和,说明数组中所有的元素都为负,那么返回最大子串和,就是所有负数中最大的那个
if summ == finalmin:
return finalmax
#如果不是,返回数组元素的和减去全局最小子串的值,得到的值要么是和全局最大子串和相等,也就是没有出现最大子串和包含数组的开头和结尾处的元素的情况,或是得到的值大于全局最大子串和,也就是出现了最大子串和包含数组的开头和结尾处的元素的情况
#还有一种情况是,数组中所有的元素都为正,所以这时候全局最小子串的值为数组中值最小的正数,那么summ减去全局最小子串一定小于全局最大子串(也就是数组所有元素的和),则返回全局最大子串
return max(summ - finalmin,finalmax)
- 完整代码:
加上判断给定的数组是否为空的情况,如果为空,返回空
class Solution(object):
def maxSubarraySumCircular(self, A):
"""
:type A: List[int]
:rtype: int
"""
if len(A) == 0:
return None
localmax = A[0]
localmin = A[0]
finalmin = A[0]
finalmax = A[0]
summ = A[0]
for i in range(1,len(A)):
summ += A[i]
if localmax + A[i] > A[i]:
localmax += A[i]
else:
localmax = A[i]
finalmax = max(localmax , finalmax)
if localmin + A[i] < A[i]:
localmin += A[i]
else:
localmin = A[i]
finalmin = min(localmin , finalmin)
if summ == finalmin:
return finalmax
return max(summ - finalmin,finalmax)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。