连续子向量的最大和问题(Python实现)

问题:

输入:一个向量x,包含n个数。

输出:向量的连续子向量的最大和,以及下标。

 

首先给出运行结果:

[1, 2, 3, 4]
low= 0 ;high= 4 ;max_sum= 10


[-11, -2, -3, -4]
NULL vector: max_sum = 0


[-1, -2, -3, 4]
low= 3 ;high= 4 ;max_sum= 4


[1, -2, -3, -4]
low= 0 ;high= 1 ;max_sum= 1


[-1, 2, 3, -4]
low= 1 ;high= 3 ;max_sum= 5


[31, -41, 59, 26, -53, 58, 97, -93, -23, 84]
low= 2 ;high= 7 ;max_sum= 187

算法分析:

有限状态机来解这道题,时间复杂度是O(n). 注:显而易见,如果使用暴力算法的话时间复杂度为O(n^3)。

状态:start, skip, state1, state2, state3, exit

判断条件:元素正负,下表是否在范围内。

根据判断条件在状态件切换,并且记录下表和最大和。

 

Python实现的源码

#!/usr/bin/python
# identify the subvector in a given vector that has the maximum sum

# Global Vars
max_sum = 0
high = 0
low = 0
minus_sum = 0
cur_sum = 0
cur_low = 0
vector = [1, 2, 3, 4]
#vector = [-1, -1, -1, -1]
#vector = [-1, -1, -1, 1]

def check_range(pos):
    global vector
    if pos >= 0 and pos < len(vector):
        return True
    else:
        return False

def do_start(pos):
    global vector
    global low
    if not check_range(pos):
        do_exit()
        return
    if vector[pos] > 0:
        low = pos
        do_state1(pos)
        return
    else:
        do_skip(pos)
        return

def do_exit():
    global low
    global high
    global cur_sum
    global minu_sum
    global cur_low
    global max_sum
    if low >= high:
        print 'NULL vector: max_sum = 0'
    else:
        print 'low=', low, ';high=', high, ';max_sum=', max_sum
    cur_sum = 0
    max_sum = 0
    cur_low = 0
    minus_sum = 0
    low = 0
    high = 0
    return


def do_skip(pos):
    global vector
    global low
    if not check_range(pos):
        do_exit()
        return
    while vector[pos] <= 0:
        pos += 1
        if not check_range(pos):
            do_exit()
            return
    if vector[pos] > 0:
        low = pos
        do_state1(pos)
        return
    else:
        print 'we should never get here!'
        return

def do_state1(pos):
    global max_sum
    global vector
    global high
    max_sum += vector[pos]
    high = pos+1                # [low, high)
    pos += 1
    if not check_range(pos):
        do_exit()
        return
    if vector[pos] > 0:
        do_state1(pos)
        return
    else:
        do_state2(pos)
        return

def do_state2(pos):
    global minus_sum
    global vector
    global cur_low
    minus_sum += vector[pos]
    pos += 1
    if not check_range(pos):
        do_exit()
        return
    if vector[pos] > 0:
        cur_low = pos
        do_state3(pos)
        return
    else:
        do_state2(pos)
        return

def do_state3(pos):
    global vector
    global cur_sum
    cur_sum += vector[pos]
    pos += 1
    if not check_range(pos):
        determine_and_reset(pos)
        do_exit()
        return
    if vector[pos] > 0:
        do_state3(pos)
        return
    else:
        determine_and_reset(pos)
        do_state2(pos)
        return

def determine_and_reset(pos):
    global minus_sum
    global max_sum
    global cur_sum
    global cur_low
    global vector
    global low
    global high
    sum_total = max_sum + minus_sum + cur_sum
    if sum_total > max_sum and sum_total > cur_sum:
        high = pos
        low = low
        max_sum = sum_total
    elif cur_sum >= sum_total and cur_sum > max_sum:
        high = pos
        low = cur_low
        max_sum = cur_sum
    elif max_sum >= sum_total and max_sum >= cur_sum:
        high = high
        low = low
    else:
        print 'we should never get here!'
    cur_sum = 0
    cur_low = 0
    minus_sum = 0

    
def test1():
    global vector
    vector = [1, 2, 3, 4]
    print vector
    do_start(0)

def test2():
    global vector
    vector = [-11, -2, -3, -4]
    print vector
    do_start(0)

def test3():
    global vector
    vector = [-1, -2, -3, 4]
    print vector
    do_start(0)

def test4():
    global vector
    vector = [1, -2, -3, -4]
    print vector
    do_start(0)

def test5():
    global vector
    vector = [-1, 2, 3, -4]
    print vector
    do_start(0)

def test6():
    global vector
    vector = [31, -41, 59, 26, -53, 58, 97, -93, -23, 84]
    print vector
    do_start(0)


def main():
    test1()
    test2()
    test3()
    test4()
    test5()
    test6()
    return 0

if __name__ == '__main__':
    main()

 

 

 

转载于:https://my.oschina.net/u/158589/blog/61137

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值