嗯。。。过完春节了,开始捡起学习的进程(真香)。。。开始看mooc浙大的数据结构与算法(姥姥版)
C++我之前稍微接触了一点点,也仅仅是学到函数部分,唉,刷题不易,要是能刷过PAT的顶级,估计离合格的程序员也不远了吧?
总之。。。。新的一年,新的作死!
第一种解法:豹腻解法2
class Solution:
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) == 1:
return nums[0]
join =[]
for i in range(len(nums)):
solu = []
solu.append(nums[i])
for j in range(i+1,len(nums)):
solu.append(nums[j])
#print(solu,sum(solu))
join.append(sum(solu))
if max(join) <= max(nums):
return max(nums)
return (max(join))
嗯,这个解法是O(n2)的。。。为嘛代码框不是黑底的了。。强迫症犯了。。
当然还有O(n)和O(logn)复杂度的,稍后开始尝试
第二种解法:累积遍历算法/在线处理/凸包算法(Graham扫描法)
(这居然是有证明的。。。一个统计学家提出来的)不会证明的数据分析师不是好程序员,我开始寻找这个算法的证明过程(莫名其妙涉及到了凸包算法)
https://www.cnblogs.com/nowgood/p/GrahamconvexHull.html
为什么要把最大子序和当成凸包呢?这里给的是一个固定数组,为什么要在累计为0的时候舍弃前面的值呢?(小于0就会分裂成两块了)
https://blog.csdn.net/zwzsdy/article/details/80029796
https://blog.csdn.net/samjustin1/article/details/52043369
没有数学公式介绍确实真的不好看懂。。。这个数学问题是怎么转化的呢?
好吧。。。这个问题留给后人。。
那么我们来试一试这个方法
class Solution:
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) == 1:
return nums[0]
solu,slide = 0,0
for i in range(len(nums)):
slide += nums[i]
if slide > solu:
solu = slide
elif slide <= 0:
slide = 0
return solu
额,理想很美好,然后就报错了,什么呢?就是全是负数的情况下,失效了,会输出0
这里有明显的一个bug就是遇到0便舍去,完全没有考虑到负数大小的排序
怎么改进这个算法确实想不清楚,最大的便捷成了最大的阻碍,姥姥你坑我!
那么下面继续试试
第三种解法:动态规划
class Solution:
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) == 1:
return nums[0]
cur = nums[:]
maxSum = nums[0]
for i in range(1,len(nums)):
if cur[i-1] > 0:
cur[i]= nums[i]+cur[i-1]
if cur[i]>maxSum:
maxSum = cur[i]
return maxSum
最关键的点是,用目前序列和对比目前指针位数字,如果大,则用目前指针位数字代替,非常的精妙,比小于0就舍弃不知道高到哪里去了。
第四种解法:分治法
分治法自己没有学过,看姥姥的用法是
class Solution(object):
def maxSubArray(self, nums):
left = 0
right = len(nums)-1
maxSum = self.divide(nums,left,right)
return maxSum
def divide(self,nums,left,right):
if left==right:
return nums[left]
# 但是这里要注意要用取余,不然的话,指针不能读取浮点小数值
center = (left+right)//2
leftMaxSum = self.divide(nums,left,center)
rightMaxSum = self.divide(nums,center+1,right)
leftBorderSum = nums[center]
leftSum = nums[center]
for i in range(center-1,left-1,-1):
leftSum += nums[i]
if leftSum>leftBorderSum:
leftBorderSum = leftSum
rightBorderSum = nums[center+1]
rightSum = nums[center+1]
for i in range(center+2,right+1):
rightSum += nums[i]
if rightSum>rightBorderSum:
rightBorderSum = rightSum
BorderSum = leftBorderSum + rightBorderSum
return max(leftMaxSum,rightMaxSum,BorderSum)
更改自 https://blog.csdn.net/Jaster_wisdom/article/details/80662037
。。。。。。目前只能做到领悟思想。。。。
我自己的想法是用log2(长度)先切成两辆一组的
但是这个迭代方法确实比自己先切方便。。。。总之就是有点懒了。。。。然后应该有更精妙的写法,等更新好了。。
2019/2/15 15:25:38
--------------------------------------------------------------------------------------------------------------------------------------------------------------------