最大子序列和-线段树问题

对于范围的问题,例如最大子序列,最小子序列等都可以使用线段树来解决。

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

你可能感兴趣的:(最大子序列和-线段树问题)