对于范围的问题,例如最大子序列,最小子序列等都可以使用线段树来解决。
segment_tree.jpg线段树每个节点指向左右范围节点left,right,还需要保存范围内的[最大值或者最小值]ivalue, 当前值value,左侧的最大值:left_value, 右侧的最大值: right_value.
每次计算的时候,计算左侧的最大值为: max(left.right_value ,left.right_value+value), 右侧的最大值为: max(right.left_value, right_left_value+value)
再计算左侧和右侧的最大值max(left_value, right_value, left_value+right_value)为这个范围大最大连续和
注意: 因为需要连续,所以左侧最大值只能为left.right_value+value, value的最大值
class SegmentNode(object):
def __init__(self, value):
self.Lvalue = 0
self.Rvalue = 0
self.value = value
self.left = None
self.right = None
self.Ivalue = 0
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
segment = self.search(nums)
return segment.Ivalue
def search(self, nums):
l, r = 0, len(nums) - 1
middle = (l + r) / 2
if l == r:
return SegmentNode(nums[l])
else:
left_segment = self.search(nums[: middle])
rigt_segment = self.search(nums[middle+1: ])
segment = SegmentNode(num[middle])
lvalue = max(left.right_value, nums[middle] + left.right_value)
rvalue = max(right.left_value, nums[middle] + right.left_value)
ivalue = max(lvalue, rvalue, lvalue+rvalue)
segment.left = left_segment
segment.right = rigt_segment
segment.Lvalue = lvalue
segment.Rvalue = rvalue
segment.Ivalue = ivalue
return segment
或者采用滚动数组来实现
def Solution(nums):
pre, max_result = 0, nums[0]
for i in nums:
pre = max(nums[i] + pre, nums[i])
max_result = max(pre, max_result)
return max_result
网友评论