面试150 环形子数组的最大和
思路
通过分情况处理,先求出非环形情况下的最大子数组和(max_sum),然后用类似方式求出最小子数组和(min_sum)。由于环形最大子数组可能由总数组和减去中间最小子数组得到,因此再计算总和 total - min_sum 与 max_sum 进行比较,取两者的较大值作为最终答案。注意到如果数组全为负数,此时 total - min_sum 等于 0,会误导结果,因此单独判断 max_num < 0 的情况,直接返回最大值,避免错误。该方法充分利用了Kadane算法的优雅特性,时间复杂度为 O(n)。
class Solution:def maxSubarraySumCircular(self, nums: List[int]) -> int:def max_sum(nums):cur=max_num=nums[0]for num in nums[1:]:cur=max(num,num+cur)max_num=max(max_num,cur)return max_numdef min_sum(nums):cur=min_num=nums[0]for num in nums[1:]:cur=min(num,num+cur)min_num=min(min_num,cur)return min_numtotal=sum(nums)max_num=max_sum(nums)min_num=min_sum(nums)if max_num<0:return max_num #如果没有这样的话,最后会返回0,不走下面那步return max(max_num,total-min_num)