问题:
输入:一个向量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()