LeetCode53最大子序和

未经博主同意,禁止瞎JB转载。

LeetCode53最大子序和

https://leetcode-cn.com/problems/maximum-subarray/description/

我的解法:

 1 class Solution(object):
 2     def maxSubArray(self, nums):
 3         """
 4         :type nums: List[int]
 5         :rtype: int
 6         """
 7         sumer = 0
 8         maxer = nums[0]
 9         for i in nums:
10             sumer += i
11             if maxer < 0:
12                 maxer = max(maxer,i)
13             else:
14                 maxer = max(maxer,sumer)
15             if sumer<0:
16                 sumer = 0
17         return maxer

 其实11-13行可以删除,变成:

 1 class Solution(object):
 2     def maxSubArray(self, nums):
 3         """
 4         :type nums: List[int]
 5         :rtype: int
 6         """
 7         sumer = 0
 8         maxer = nums[0]
 9         for i in nums:
10             sumer += i
11             maxer = max(maxer,sumer)
12             if sumer<0:
13                 sumer = 0
14         return maxer

 更好的解决方案参考:

https://blog.csdn.net/weixin_41958153/article/details/81131379

动态规划:

 1 class Solution:
 2  
 3   
 4     def maxSubArray(self, nums):  
 5         """ 
 6         :type nums: List[int] 
 7         :rtype: int 
 8         """  
 9         length=len(nums)  
10         for i in range(1,length):  
11             #当前值的大小与前面的值之和比较,若当前值更大,则取当前值,舍弃前面的值之和  
12             subMaxSum=max(nums[i]+nums[i-1],nums[i])  
13             nums[i]=subMaxSum#将当前和最大的赋给nums[i],新的nums存储的为和值  
14         return max(nums) 

分而治之:

 1 class Solution(object):
 2     def maxSubArray(self, nums):
 3         #主函数
 4         left = 0
 5         #左右边界
 6         right = len(nums)-1
 7         #求最大和
 8         maxSum = self.divide(nums,left,right)
 9         return maxSum
10         
11     def divide(self,nums,left,right):
12         #如果只有一个元素就返回
13         if left==right:
14             return nums[left]
15         #确立中心点
16         center = (left+right)//2
17         #求子序在中心点左边的和
18         leftMaxSum = self.divide(nums,left,center)
19         #求子序在中心点右边的和
20         rightMaxSum = self.divide(nums,center+1,right)
21         
22         #求子序横跨2边的和,分成左边界和和右边界和
23         leftBorderSum = nums[center]
24         leftSum = nums[center]
25         for i in range(center-1,left-1,-1):
26             leftSum += nums[i]
27             if leftSum>leftBorderSum:
28                 #不断更新左区块的最大值
29                 leftBorderSum = leftSum
30             
31         rightBorderSum = nums[center+1]
32         rightSum = nums[center+1]
33         for i in range(center+2,right+1):
34             rightSum += nums[i]
35             if rightSum>rightBorderSum:
36                 #不断更新右区块的最大值
37                 rightBorderSum = rightSum
38         #左边界的和 + 右边那块的和
39         BorderSum = leftBorderSum + rightBorderSum
40         return max(leftMaxSum,rightMaxSum,BorderSum)

 个人认为分治法虽然分治法时间复杂度降到了O(nlogn),但是代码复杂度较高,性价比在实现层面对于小数据集不高。

posted @ 2018-10-09 21:46  嬴政有条北冥的鱼  阅读(115)  评论(0编辑  收藏  举报